~ubuntu-branches/debian/stretch/alpine/stretch

« back to all changes in this revision

Viewing changes to imap/src/osdep/amiga/phile.c

  • Committer: Bazaar Package Importer
  • Author(s): Asheesh Laroia
  • Date: 2007-02-17 13:17:42 UTC
  • Revision ID: james.westby@ubuntu.com-20070217131742-99x5c6cpg1pbkdhw
Tags: upstream-0.82+dfsg
ImportĀ upstreamĀ versionĀ 0.82+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ========================================================================
 
2
 * Copyright 1988-2006 University of Washington
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * 
 
11
 * ========================================================================
 
12
 */
 
13
 
 
14
/*
 
15
 * Program:     File routines
 
16
 *
 
17
 * Author:      Mark Crispin
 
18
 *              Networks and Distributed Computing
 
19
 *              Computing & Communications
 
20
 *              University of Washington
 
21
 *              Administration Building, AG-44
 
22
 *              Seattle, WA  98195
 
23
 *              Internet: MRC@CAC.Washington.EDU
 
24
 *
 
25
 * Date:        25 August 1993
 
26
 * Last Edited: 30 August 2006
 
27
 */
 
28
 
 
29
 
 
30
#include <stdio.h>
 
31
#include <ctype.h>
 
32
#include <errno.h>
 
33
extern int errno;               /* just in case */
 
34
#include <signal.h>
 
35
#include "mail.h"
 
36
#include "osdep.h"
 
37
#include <pwd.h>
 
38
#include <sys/stat.h>
 
39
#include <sys/time.h>
 
40
#include "rfc822.h"
 
41
#include "misc.h"
 
42
#include "dummy.h"
 
43
 
 
44
/* Types returned from phile_type() */
 
45
 
 
46
#define PTYPEBINARY 0           /* binary data */
 
47
#define PTYPETEXT 1             /* textual data */
 
48
#define PTYPECRTEXT 2           /* textual data with CR */
 
49
#define PTYPE8 4                /* textual 8bit data */
 
50
#define PTYPEISO2022JP 8        /* textual Japanese */
 
51
#define PTYPEISO2022KR 16       /* textual Korean */
 
52
#define PTYPEISO2022CN 32       /* textual Chinese */
 
53
 
 
54
 
 
55
/* PHILE I/O stream local data */
 
56
        
 
57
typedef struct phile_local {
 
58
  ENVELOPE *env;                /* file envelope */
 
59
  BODY *body;                   /* file body */
 
60
  char tmp[MAILTMPLEN];         /* temporary buffer */
 
61
} PHILELOCAL;
 
62
 
 
63
 
 
64
/* Convenient access to local data */
 
65
 
 
66
#define LOCAL ((PHILELOCAL *) stream->local)
 
67
 
 
68
 
 
69
/* Function prototypes */
 
70
 
 
71
DRIVER *phile_valid (char *name);
 
72
int phile_isvalid (char *name,char *tmp);
 
73
void *phile_parameters (long function,void *value);
 
74
void phile_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);
 
75
void phile_list (MAILSTREAM *stream,char *ref,char *pat);
 
76
void phile_lsub (MAILSTREAM *stream,char *ref,char *pat);
 
77
long phile_create (MAILSTREAM *stream,char *mailbox);
 
78
long phile_delete (MAILSTREAM *stream,char *mailbox);
 
79
long phile_rename (MAILSTREAM *stream,char *old,char *newname);
 
80
long phile_status (MAILSTREAM *stream,char *mbx,long flags);
 
81
MAILSTREAM *phile_open (MAILSTREAM *stream);
 
82
int phile_type (unsigned char *s,unsigned long i,unsigned long *j);
 
83
void phile_close (MAILSTREAM *stream,long options);
 
84
ENVELOPE *phile_structure (MAILSTREAM *stream,unsigned long msgno,BODY **body,
 
85
                           long flags);
 
86
char *phile_header (MAILSTREAM *stream,unsigned long msgno,
 
87
                    unsigned long *length,long flags);
 
88
long phile_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);
 
89
long phile_ping (MAILSTREAM *stream);
 
90
void phile_check (MAILSTREAM *stream);
 
91
long phile_expunge (MAILSTREAM *stream,char *sequence,long options);
 
92
long phile_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);
 
93
long phile_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);
 
94
 
 
95
/* File routines */
 
96
 
 
97
 
 
98
/* Driver dispatch used by MAIL */
 
99
 
 
100
DRIVER philedriver = {
 
101
  "phile",                      /* driver name */
 
102
                                /* driver flags */
 
103
  DR_LOCAL|DR_READONLY|DR_NOSTICKY,
 
104
  (DRIVER *) NIL,               /* next driver */
 
105
  phile_valid,                  /* mailbox is valid for us */
 
106
  phile_parameters,             /* manipulate parameters */
 
107
  phile_scan,                   /* scan mailboxes */
 
108
  phile_list,                   /* list mailboxes */
 
109
  phile_lsub,                   /* list subscribed mailboxes */
 
110
  NIL,                          /* subscribe to mailbox */
 
111
  NIL,                          /* unsubscribe from mailbox */
 
112
  dummy_create,                 /* create mailbox */
 
113
  dummy_delete,                 /* delete mailbox */
 
114
  dummy_rename,                 /* rename mailbox */
 
115
  phile_status,                 /* status of mailbox */
 
116
  phile_open,                   /* open mailbox */
 
117
  phile_close,                  /* close mailbox */
 
118
  NIL,                          /* fetch message "fast" attributes */
 
119
  NIL,                          /* fetch message flags */
 
120
  NIL,                          /* fetch overview */
 
121
  phile_structure,              /* fetch message envelopes */
 
122
  phile_header,                 /* fetch message header only */
 
123
  phile_text,                   /* fetch message body only */
 
124
  NIL,                          /* fetch partial message text */
 
125
  NIL,                          /* unique identifier */
 
126
  NIL,                          /* message number */
 
127
  NIL,                          /* modify flags */
 
128
  NIL,                          /* per-message modify flags */
 
129
  NIL,                          /* search for message based on criteria */
 
130
  NIL,                          /* sort messages */
 
131
  NIL,                          /* thread messages */
 
132
  phile_ping,                   /* ping mailbox to see if still alive */
 
133
  phile_check,                  /* check for new messages */
 
134
  phile_expunge,                /* expunge deleted messages */
 
135
  phile_copy,                   /* copy messages to another mailbox */
 
136
  phile_append,                 /* append string message to mailbox */
 
137
  NIL                           /* garbage collect stream */
 
138
};
 
139
 
 
140
                                /* prototype stream */
 
141
MAILSTREAM phileproto = {&philedriver};
 
142
 
 
143
/* File validate mailbox
 
144
 * Accepts: mailbox name
 
145
 * Returns: our driver if name is valid, NIL otherwise
 
146
 */
 
147
 
 
148
DRIVER *phile_valid (char *name)
 
149
{
 
150
  char tmp[MAILTMPLEN];
 
151
  return phile_isvalid (name,tmp) ? &philedriver : NIL;
 
152
}
 
153
 
 
154
 
 
155
/* File test for valid mailbox
 
156
 * Accepts: mailbox name
 
157
 * Returns: T if valid, NIL otherwise
 
158
 */
 
159
 
 
160
int phile_isvalid (char *name,char *tmp)
 
161
{
 
162
  struct stat sbuf;
 
163
  char *s;
 
164
                                /* INBOX never accepted, any other name is */
 
165
  return ((s = mailboxfile (tmp,name)) && *s && !stat (s,&sbuf) &&
 
166
          !(sbuf.st_mode & S_IFDIR) &&
 
167
                                /* only allow empty files if #ftp */
 
168
          (sbuf.st_size || ((*name == '#') &&
 
169
                            ((name[1] == 'f') || (name[1] == 'F')) &&
 
170
                            ((name[2] == 't') || (name[2] == 'T')) &&
 
171
                            ((name[3] == 'p') || (name[3] == 'P')) &&
 
172
                            (name[4] == '/'))));
 
173
}
 
174
 
 
175
/* File manipulate driver parameters
 
176
 * Accepts: function code
 
177
 *          function-dependent value
 
178
 * Returns: function-dependent return value
 
179
 */
 
180
 
 
181
void *phile_parameters (long function,void *value)
 
182
{
 
183
  return NIL;
 
184
}
 
185
 
 
186
/* File mail scan mailboxes
 
187
 * Accepts: mail stream
 
188
 *          reference
 
189
 *          pattern to search
 
190
 *          string to scan
 
191
 */
 
192
 
 
193
void phile_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents)
 
194
{
 
195
  if (stream) dummy_scan (NIL,ref,pat,contents);
 
196
}
 
197
 
 
198
 
 
199
/* File list mailboxes
 
200
 * Accepts: mail stream
 
201
 *          reference
 
202
 *          pattern to search
 
203
 */
 
204
 
 
205
void phile_list (MAILSTREAM *stream,char *ref,char *pat)
 
206
{
 
207
  if (stream) dummy_list (NIL,ref,pat);
 
208
}
 
209
 
 
210
 
 
211
/* File list subscribed mailboxes
 
212
 * Accepts: mail stream
 
213
 *          reference
 
214
 *          pattern to search
 
215
 */
 
216
 
 
217
void phile_lsub (MAILSTREAM *stream,char *ref,char *pat)
 
218
{
 
219
  if (stream) dummy_lsub (NIL,ref,pat);
 
220
}
 
221
 
 
222
 
 
223
/* File status
 
224
 * Accepts: mail stream
 
225
 *          mailbox name
 
226
 *          status flags
 
227
 * Returns: T on success, NIL on failure
 
228
 */
 
229
 
 
230
long phile_status (MAILSTREAM *stream,char *mbx,long flags)
 
231
{
 
232
  char *s,tmp[MAILTMPLEN];
 
233
  MAILSTATUS status;
 
234
  struct stat sbuf;
 
235
  long ret = NIL;
 
236
  if ((s = mailboxfile (tmp,mbx)) && *s && !stat (s,&sbuf)) {
 
237
    status.flags = flags;       /* return status values */
 
238
    status.unseen = (stream && mail_elt (stream,1)->seen) ? 0 : 1;
 
239
    status.messages = status.recent = status.uidnext = 1;
 
240
    status.uidvalidity = sbuf.st_mtime;
 
241
                                /* pass status to main program */
 
242
    mm_status (stream,mbx,&status);
 
243
    ret = LONGT;                /* success */
 
244
  }
 
245
  return ret;
 
246
}
 
247
 
 
248
/* File open
 
249
 * Accepts: Stream to open
 
250
 * Returns: Stream on success, NIL on failure
 
251
 */
 
252
 
 
253
MAILSTREAM *phile_open (MAILSTREAM *stream)
 
254
{
 
255
  int i,k,fd;
 
256
  unsigned long j,m;
 
257
  char *s,tmp[MAILTMPLEN];
 
258
  struct passwd *pw;
 
259
  struct stat sbuf;
 
260
  struct tm *t;
 
261
  MESSAGECACHE *elt;
 
262
  SIZEDTEXT *buf;
 
263
                                /* return prototype for OP_PROTOTYPE call */
 
264
  if (!stream) return &phileproto;
 
265
  if (stream->local) fatal ("phile recycle stream");
 
266
                                /* open associated file */
 
267
  if (!mailboxfile (tmp,stream->mailbox) || !tmp[0] || stat (tmp,&sbuf) ||
 
268
      (fd = open (tmp,O_RDONLY,NIL)) < 0) {
 
269
    sprintf (tmp,"Unable to open file %s",stream->mailbox);
 
270
    mm_log (tmp,ERROR);
 
271
    return NIL;
 
272
  }
 
273
  fs_give ((void **) &stream->mailbox);
 
274
  stream->mailbox = cpystr (tmp);
 
275
  stream->local = fs_get (sizeof (PHILELOCAL));
 
276
  mail_exists (stream,1);       /* make sure upper level knows */
 
277
  mail_recent (stream,1);
 
278
  elt = mail_elt (stream,1);    /* instantiate cache element */
 
279
  elt->valid = elt->recent = T; /* mark valid flags */
 
280
  stream->sequence++;           /* bump sequence number */
 
281
  stream->rdonly = T;           /* make sure upper level knows readonly */
 
282
                                /* instantiate a new envelope and body */
 
283
  LOCAL->env = mail_newenvelope ();
 
284
  LOCAL->body = mail_newbody ();
 
285
 
 
286
  t = gmtime (&sbuf.st_mtime);  /* get UTC time and Julian day */
 
287
  i = t->tm_hour * 60 + t->tm_min;
 
288
  k = t->tm_yday;
 
289
  t = localtime(&sbuf.st_mtime);/* get local time */
 
290
                                /* calculate time delta */
 
291
  i = t->tm_hour * 60 + t->tm_min - i;
 
292
  if (k = t->tm_yday - k) i += ((k < 0) == (abs (k) == 1)) ? -24*60 : 24*60;
 
293
  k = abs (i);                  /* time from UTC either way */
 
294
  elt->hours = t->tm_hour; elt->minutes = t->tm_min; elt->seconds = t->tm_sec;
 
295
  elt->day = t->tm_mday; elt->month = t->tm_mon + 1;
 
296
  elt->year = t->tm_year - (BASEYEAR - 1900);
 
297
  elt->zoccident = (k == i) ? 0 : 1;
 
298
  elt->zhours = k/60;
 
299
  elt->zminutes = k % 60;
 
300
  sprintf (tmp,"%s, %d %s %d %02d:%02d:%02d %c%02d%02d",
 
301
           days[t->tm_wday],t->tm_mday,months[t->tm_mon],t->tm_year+1900,
 
302
           t->tm_hour,t->tm_min,t->tm_sec,elt->zoccident ? '-' : '+',
 
303
           elt->zhours,elt->zminutes);
 
304
                                /* set up Date field */
 
305
  LOCAL->env->date = cpystr (tmp);
 
306
 
 
307
                                /* fill in From field from file owner */
 
308
  LOCAL->env->from = mail_newaddr ();
 
309
  if (pw = getpwuid (sbuf.st_uid)) strcpy (tmp,pw->pw_name);
 
310
  else sprintf (tmp,"User-Number-%ld",(long) sbuf.st_uid);
 
311
  LOCAL->env->from->mailbox = cpystr (tmp);
 
312
  LOCAL->env->from->host = cpystr (mylocalhost ());
 
313
                                /* set subject to be mailbox name */
 
314
  LOCAL->env->subject = cpystr (stream->mailbox);
 
315
                                /* slurp the data */
 
316
  (buf = &elt->private.special.text)->size = sbuf.st_size;
 
317
  read (fd,buf->data = (unsigned char *) fs_get (buf->size + 1),buf->size);
 
318
  buf->data[buf->size] = '\0';
 
319
  close (fd);                   /* close the file */
 
320
                                /* analyze data type */
 
321
  if (i = phile_type (buf->data,buf->size,&j)) {
 
322
    LOCAL->body->type = TYPETEXT;
 
323
    LOCAL->body->subtype = cpystr ("PLAIN");
 
324
    if (!(i & PTYPECRTEXT)) {   /* change Internet newline format as needed */
 
325
      s = (char *) buf->data;   /* make copy of UNIX-format string */
 
326
      buf->data = NIL;          /* zap the buffer */
 
327
      buf->size = strcrlfcpy (&buf->data,&m,s,buf->size);
 
328
      fs_give ((void **) &s);   /* flush original UNIX-format string */
 
329
    }
 
330
    LOCAL->body->parameter = mail_newbody_parameter ();
 
331
    LOCAL->body->parameter->attribute = cpystr ("charset");
 
332
    LOCAL->body->parameter->value =
 
333
      cpystr ((i & PTYPEISO2022JP) ? "ISO-2022-JP" :
 
334
              (i & PTYPEISO2022KR) ? "ISO-2022-KR" :
 
335
              (i & PTYPEISO2022CN) ? "ISO-2022-CN" :
 
336
              (i & PTYPE8) ? "X-UNKNOWN" : "US-ASCII");
 
337
    LOCAL->body->encoding = (i & PTYPE8) ? ENC8BIT : ENC7BIT;
 
338
    LOCAL->body->size.lines = j;
 
339
  }
 
340
  else {                        /* binary data */
 
341
    LOCAL->body->type = TYPEAPPLICATION;
 
342
    LOCAL->body->subtype = cpystr ("OCTET-STREAM");
 
343
    LOCAL->body->parameter = mail_newbody_parameter ();
 
344
    LOCAL->body->parameter->attribute = cpystr ("name");
 
345
    LOCAL->body->parameter->value =
 
346
      cpystr ((s = (strrchr (stream->mailbox,'/'))) ? s+1 : stream->mailbox);
 
347
    LOCAL->body->encoding = ENCBASE64;
 
348
    buf->data = rfc822_binary (s = (char *) buf->data,buf->size,&buf->size);
 
349
    fs_give ((void **) &s);     /* flush originary binary contents */
 
350
  }
 
351
  phile_header (stream,1,&j,NIL);
 
352
  LOCAL->body->size.bytes = LOCAL->body->contents.text.size = buf->size;
 
353
  elt->rfc822_size = j + buf->size;
 
354
                                /* only one message ever... */
 
355
  stream->uid_validity = sbuf.st_mtime;
 
356
  stream->uid_last = elt->private.uid = 1;
 
357
  return stream;                /* return stream alive to caller */
 
358
}
 
359
 
 
360
/* File determine data type
 
361
 * Accepts: data to examine
 
362
 *          size of data
 
363
 *          pointer to line count return
 
364
 * Returns: PTYPE mask of data type
 
365
 */
 
366
 
 
367
int phile_type (unsigned char *s,unsigned long i,unsigned long *j)
 
368
{
 
369
  int ret = PTYPETEXT;
 
370
  char *charvec = "bbbbbbbaaalaacaabbbbbbbbbbbebbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
 
371
  *j = 0;                       /* no lines */
 
372
                                /* check type of every character */
 
373
  while (i--) switch (charvec[*s++]) {
 
374
  case 'A':
 
375
    ret |= PTYPE8;              /* 8bit character */
 
376
    break;
 
377
  case 'a':
 
378
    break;                      /* ASCII character */
 
379
  case 'b':
 
380
    return PTYPEBINARY;         /* binary byte seen, stop immediately */
 
381
  case 'c':
 
382
    ret |= PTYPECRTEXT;         /* CR indicates Internet text */
 
383
    break;
 
384
  case 'e':                     /* ESC */
 
385
    if (*s == '$') {            /* ISO-2022 sequence? */
 
386
      switch (s[1]) {
 
387
      case 'B': case '@': ret |= PTYPEISO2022JP; break;
 
388
      case ')':
 
389
        switch (s[2]) {
 
390
        case 'A': case 'E': case 'G': ret |= PTYPEISO2022CN; break;
 
391
        case 'C': ret |= PTYPEISO2022KR; break;
 
392
        }
 
393
      case '*':
 
394
        switch (s[2]) {
 
395
        case 'H': ret |= PTYPEISO2022CN; break;
 
396
        }
 
397
      case '+':
 
398
        switch (s[2]) {
 
399
        case 'I': case 'J': case 'K': case 'L': case 'M':
 
400
          ret |= PTYPEISO2022CN; break;
 
401
        }
 
402
      }
 
403
    }
 
404
    break;
 
405
  case 'l':                     /* newline */
 
406
    (*j)++;
 
407
    break;
 
408
  }
 
409
  return ret;                   /* return type of data */
 
410
}
 
411
 
 
412
/* File close
 
413
 * Accepts: MAIL stream
 
414
 *          close options
 
415
 */
 
416
 
 
417
void phile_close (MAILSTREAM *stream,long options)
 
418
{
 
419
  if (LOCAL) {                  /* only if a file is open */
 
420
    fs_give ((void **) &mail_elt (stream,1)->private.special.text.data);
 
421
                                /* nuke the local data */
 
422
    fs_give ((void **) &stream->local);
 
423
    stream->dtb = NIL;          /* log out the DTB */
 
424
  }
 
425
}
 
426
 
 
427
/* File fetch structure
 
428
 * Accepts: MAIL stream
 
429
 *          message # to fetch
 
430
 *          pointer to return body
 
431
 *          option flags
 
432
 * Returns: envelope of this message, body returned in body value
 
433
 *
 
434
 * Fetches the "fast" information as well
 
435
 */
 
436
 
 
437
ENVELOPE *phile_structure (MAILSTREAM *stream,unsigned long msgno,BODY **body,
 
438
                           long flags)
 
439
{
 
440
  if (body) *body = LOCAL->body;
 
441
  return LOCAL->env;            /* return the envelope */
 
442
}
 
443
 
 
444
 
 
445
/* File fetch message header
 
446
 * Accepts: MAIL stream
 
447
 *          message # to fetch
 
448
 *          pointer to returned header text length
 
449
 *          option flags
 
450
 * Returns: message header in RFC822 format
 
451
 */
 
452
 
 
453
char *phile_header (MAILSTREAM *stream,unsigned long msgno,
 
454
                    unsigned long *length,long flags)
 
455
{
 
456
  rfc822_header (LOCAL->tmp,LOCAL->env,LOCAL->body);
 
457
  *length = strlen (LOCAL->tmp);
 
458
  return LOCAL->tmp;
 
459
}
 
460
 
 
461
 
 
462
/* File fetch message text (body only)
 
463
 * Accepts: MAIL stream
 
464
 *          message # to fetch
 
465
 *          pointer to returned stringstruct
 
466
 *          option flags
 
467
 * Returns: T, always
 
468
 */
 
469
 
 
470
long phile_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags)
 
471
{
 
472
  SIZEDTEXT *buf = &mail_elt (stream,msgno)->private.special.text;
 
473
  if (!(flags &FT_PEEK)) {      /* mark message as seen */
 
474
    mail_elt (stream,msgno)->seen = T;
 
475
    mm_flags (stream,msgno);
 
476
  }
 
477
  INIT (bs,mail_string,buf->data,buf->size);
 
478
  return T;
 
479
}
 
480
 
 
481
/* File ping mailbox
 
482
 * Accepts: MAIL stream
 
483
 * Returns: T if stream alive, else NIL
 
484
 * No-op for readonly files, since read/writer can expunge it from under us!
 
485
 */
 
486
 
 
487
long phile_ping (MAILSTREAM *stream)
 
488
{
 
489
  return T;
 
490
}
 
491
 
 
492
/* File check mailbox
 
493
 * Accepts: MAIL stream
 
494
 * No-op for readonly files, since read/writer can expunge it from under us!
 
495
 */
 
496
 
 
497
void phile_check (MAILSTREAM *stream)
 
498
{
 
499
  mm_log ("Check completed",NIL);
 
500
}
 
501
 
 
502
/* File expunge mailbox
 
503
 * Accepts: MAIL stream
 
504
 *          sequence to expunge if non-NIL
 
505
 *          expunge options
 
506
 * Returns: T if success, NIL if failure
 
507
 */
 
508
 
 
509
long phile_expunge (MAILSTREAM *stream,char *sequence,long options)
 
510
{
 
511
  if (!stream->silent) mm_log ("Expunge ignored on readonly mailbox",NIL);
 
512
  return LONGT;
 
513
}
 
514
 
 
515
/* File copy message(s)
 
516
 * Accepts: MAIL stream
 
517
 *          sequence
 
518
 *          destination mailbox
 
519
 *          copy options
 
520
 * Returns: T if copy successful, else NIL
 
521
 */
 
522
 
 
523
long phile_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
 
524
{
 
525
  char tmp[MAILTMPLEN];
 
526
  mailproxycopy_t pc =
 
527
    (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);
 
528
  if (pc) return (*pc) (stream,sequence,mailbox,options);
 
529
  sprintf (tmp,"Can't copy - file \"%s\" is not in valid mailbox format",
 
530
           stream->mailbox);
 
531
  mm_log (tmp,ERROR);
 
532
  return NIL;
 
533
}
 
534
 
 
535
 
 
536
/* File append message from stringstruct
 
537
 * Accepts: MAIL stream
 
538
 *          destination mailbox
 
539
 *          append callback function
 
540
 *          data for callback
 
541
 * Returns: T if append successful, else NIL
 
542
 */
 
543
 
 
544
long phile_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
 
545
{
 
546
  char tmp[MAILTMPLEN],file[MAILTMPLEN];
 
547
  char *s = mailboxfile (file,mailbox);
 
548
  if (s && *s) 
 
549
    sprintf (tmp,"Can't append - not in valid mailbox format: %.80s",s);
 
550
  else sprintf (tmp,"Can't append - invalid name: %.80s",mailbox);
 
551
  mm_log (tmp,ERROR);
 
552
  return NIL;
 
553
}