imapext-2007

annotate src/osdep/amiga/phile.c @ 0:ada5e610ab86

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

UW-IMAP'd extensions by yuuji