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: OS/2 environment 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: 1 August 1988
|
yuuji@0
|
26 * Last Edited: 30 August 2006
|
yuuji@0
|
27 */
|
yuuji@0
|
28
|
yuuji@0
|
29
|
yuuji@0
|
30 static char *myLocalHost = NIL; /* local host name */
|
yuuji@0
|
31 static char *myHomeDir = NIL; /* home directory name */
|
yuuji@0
|
32 static char *myNewsrc = NIL; /* newsrc file name */
|
yuuji@0
|
33 static short no822tztext = NIL; /* disable RFC [2]822 timezone text */
|
yuuji@0
|
34
|
yuuji@0
|
35 #include "write.c" /* include safe writing routines */
|
yuuji@0
|
36 #include "pmatch.c" /* include wildcard pattern matcher */
|
yuuji@0
|
37
|
yuuji@0
|
38
|
yuuji@0
|
39 /* Get all authenticators */
|
yuuji@0
|
40
|
yuuji@0
|
41 #include "auths.c"
|
yuuji@0
|
42
|
yuuji@0
|
43 /* Environment manipulate parameters
|
yuuji@0
|
44 * Accepts: function code
|
yuuji@0
|
45 * function-dependent value
|
yuuji@0
|
46 * Returns: function-dependent return value
|
yuuji@0
|
47 */
|
yuuji@0
|
48
|
yuuji@0
|
49 void *env_parameters (long function,void *value)
|
yuuji@0
|
50 {
|
yuuji@0
|
51 void *ret = NIL;
|
yuuji@0
|
52 switch ((int) function) {
|
yuuji@0
|
53 case SET_HOMEDIR:
|
yuuji@0
|
54 myHomeDir = cpystr ((char *) value);
|
yuuji@0
|
55 case GET_HOMEDIR:
|
yuuji@0
|
56 ret = (void *) myHomeDir;
|
yuuji@0
|
57 break;
|
yuuji@0
|
58 case SET_LOCALHOST:
|
yuuji@0
|
59 myLocalHost = cpystr ((char *) value);
|
yuuji@0
|
60 case GET_LOCALHOST:
|
yuuji@0
|
61 ret = (void *) myLocalHost;
|
yuuji@0
|
62 break;
|
yuuji@0
|
63 case SET_NEWSRC:
|
yuuji@0
|
64 if (myNewsrc) fs_give ((void **) &myNewsrc);
|
yuuji@0
|
65 myNewsrc = cpystr ((char *) value);
|
yuuji@0
|
66 case GET_NEWSRC:
|
yuuji@0
|
67 if (!myNewsrc) { /* set news file name if not defined */
|
yuuji@0
|
68 char tmp[MAILTMPLEN];
|
yuuji@0
|
69 sprintf (tmp,"%s\\newsrc",myhomedir ());
|
yuuji@0
|
70 myNewsrc = cpystr (tmp);
|
yuuji@0
|
71 }
|
yuuji@0
|
72 ret = (void *) myNewsrc;
|
yuuji@0
|
73 break;
|
yuuji@0
|
74 case SET_DISABLE822TZTEXT:
|
yuuji@0
|
75 no822tztext = value ? T : NIL;
|
yuuji@0
|
76 case GET_DISABLE822TZTEXT:
|
yuuji@0
|
77 ret = (void *) (no822tztext ? VOIDT : NIL);
|
yuuji@0
|
78 break;
|
yuuji@0
|
79 }
|
yuuji@0
|
80 return ret;
|
yuuji@0
|
81 }
|
yuuji@0
|
82
|
yuuji@0
|
83 /* Write current time
|
yuuji@0
|
84 * Accepts: destination string
|
yuuji@0
|
85 * optional format of day-of-week prefix
|
yuuji@0
|
86 * format of date and time
|
yuuji@0
|
87 * flag whether to append symbolic timezone
|
yuuji@0
|
88 */
|
yuuji@0
|
89
|
yuuji@0
|
90 static void do_date (char *date,char *prefix,char *fmt,int suffix)
|
yuuji@0
|
91 {
|
yuuji@0
|
92 time_t tn = time (0);
|
yuuji@0
|
93 struct tm *t = gmtime (&tn);
|
yuuji@0
|
94 int zone = t->tm_hour * 60 + t->tm_min;
|
yuuji@0
|
95 int julian = t->tm_yday;
|
yuuji@0
|
96 t = localtime (&tn); /* get local time now */
|
yuuji@0
|
97 /* minus UTC minutes since midnight */
|
yuuji@0
|
98 zone = t->tm_hour * 60 + t->tm_min - zone;
|
yuuji@0
|
99 /* julian can be one of:
|
yuuji@0
|
100 * 36x local time is December 31, UTC is January 1, offset -24 hours
|
yuuji@0
|
101 * 1 local time is 1 day ahead of UTC, offset +24 hours
|
yuuji@0
|
102 * 0 local time is same day as UTC, no offset
|
yuuji@0
|
103 * -1 local time is 1 day behind UTC, offset -24 hours
|
yuuji@0
|
104 * -36x local time is January 1, UTC is December 31, offset +24 hours
|
yuuji@0
|
105 */
|
yuuji@0
|
106 if (julian = t->tm_yday -julian)
|
yuuji@0
|
107 zone += ((julian < 0) == (abs (julian) == 1)) ? -24*60 : 24*60;
|
yuuji@0
|
108 if (prefix) { /* want day of week? */
|
yuuji@0
|
109 sprintf (date,prefix,days[t->tm_wday]);
|
yuuji@0
|
110 date += strlen (date); /* make next sprintf append */
|
yuuji@0
|
111 }
|
yuuji@0
|
112 /* output the date */
|
yuuji@0
|
113 sprintf (date,fmt,t->tm_mday,months[t->tm_mon],t->tm_year+1900,
|
yuuji@0
|
114 t->tm_hour,t->tm_min,t->tm_sec,zone/60,abs (zone) % 60);
|
yuuji@0
|
115 if (suffix) { /* append timezone suffix if desired */
|
yuuji@0
|
116 char *tz;
|
yuuji@0
|
117 tzset (); /* get timezone from TZ environment stuff */
|
yuuji@0
|
118 tz = tzname[daylight ? (((struct tm *) t)->tm_isdst > 0) : 0];
|
yuuji@0
|
119 if (tz && tz[0]) {
|
yuuji@0
|
120 char *s;
|
yuuji@0
|
121 for (s = tz; *s; s++) if (*s & 0x80) return;
|
yuuji@0
|
122 sprintf (date + strlen (date)," (%.50s)",tz);
|
yuuji@0
|
123 }
|
yuuji@0
|
124 }
|
yuuji@0
|
125 }
|
yuuji@0
|
126
|
yuuji@0
|
127
|
yuuji@0
|
128 /* Write current time in RFC 822 format
|
yuuji@0
|
129 * Accepts: destination string
|
yuuji@0
|
130 */
|
yuuji@0
|
131
|
yuuji@0
|
132 void rfc822_date (char *date)
|
yuuji@0
|
133 {
|
yuuji@0
|
134 do_date (date,"%s, ","%d %s %d %02d:%02d:%02d %+03d%02d",
|
yuuji@0
|
135 no822tztext ? NIL : T);
|
yuuji@0
|
136 }
|
yuuji@0
|
137
|
yuuji@0
|
138
|
yuuji@0
|
139 /* Write current time in fixed-width RFC 822 format
|
yuuji@0
|
140 * Accepts: destination string
|
yuuji@0
|
141 */
|
yuuji@0
|
142
|
yuuji@0
|
143 void rfc822_fixed_date (char *date)
|
yuuji@0
|
144 {
|
yuuji@0
|
145 do_date (date,NIL,"%02d %s %4d %02d:%02d:%02d %+03d%02d",NIL);
|
yuuji@0
|
146 }
|
yuuji@0
|
147
|
yuuji@0
|
148
|
yuuji@0
|
149 /* Write current time in internal format
|
yuuji@0
|
150 * Accepts: destination string
|
yuuji@0
|
151 */
|
yuuji@0
|
152
|
yuuji@0
|
153 void internal_date (char *date)
|
yuuji@0
|
154 {
|
yuuji@0
|
155 do_date (date,NIL,"%02d-%s-%d %02d:%02d:%02d %+03d%02d",NIL);
|
yuuji@0
|
156 }
|
yuuji@0
|
157
|
yuuji@0
|
158 /* Return my home directory name
|
yuuji@0
|
159 * Returns: my home directory name
|
yuuji@0
|
160 */
|
yuuji@0
|
161
|
yuuji@0
|
162 char *myhomedir ()
|
yuuji@0
|
163 {
|
yuuji@0
|
164 if (!myHomeDir) { /* get home directory name if not yet known */
|
yuuji@0
|
165 char *s;
|
yuuji@0
|
166 if ((s = getenv ("PINEHOME")) || (s = getenv ("HOME")) ||
|
yuuji@0
|
167 (s = getenv ("ETC"))) {
|
yuuji@0
|
168 myHomeDir = cpystr (s);
|
yuuji@0
|
169 while (s = strchr (myHomeDir,'/')) *s = '\\';
|
yuuji@0
|
170 if ((s = strrchr (myHomeDir,'\\')) && !s[1]) *s = '\0';
|
yuuji@0
|
171 }
|
yuuji@0
|
172 else myHomeDir = cpystr ("");
|
yuuji@0
|
173 }
|
yuuji@0
|
174 return myHomeDir;
|
yuuji@0
|
175 }
|
yuuji@0
|
176
|
yuuji@0
|
177
|
yuuji@0
|
178 /* Return mailbox file name
|
yuuji@0
|
179 * Accepts: destination buffer
|
yuuji@0
|
180 * mailbox name
|
yuuji@0
|
181 * Returns: file name
|
yuuji@0
|
182 */
|
yuuji@0
|
183
|
yuuji@0
|
184 char *mailboxfile (char *dst,char *name)
|
yuuji@0
|
185 {
|
yuuji@0
|
186 char *s;
|
yuuji@0
|
187 char *ext = (char *) mail_parameters (NIL,GET_EXTENSION,NIL);
|
yuuji@0
|
188 /* forbid extraneous extensions */
|
yuuji@0
|
189 if ((s = strchr ((s = strrchr (name,'\\')) ? s : name,'.')) &&
|
yuuji@0
|
190 ((ext = (char *) mail_parameters (NIL,GET_EXTENSION,NIL)) ||
|
yuuji@0
|
191 strchr (s+1,'.'))) return NIL;
|
yuuji@0
|
192 /* absolute path name? */
|
yuuji@0
|
193 if ((*name == '\\') || (name[1] == ':')) strcpy (dst,name);
|
yuuji@0
|
194 else sprintf (dst,"%s\\%s",myhomedir (),name);
|
yuuji@0
|
195 if (ext) sprintf (dst + strlen (dst),".%s",ext);
|
yuuji@0
|
196 return dst;
|
yuuji@0
|
197 }
|
yuuji@0
|
198
|
yuuji@0
|
199 /* Lock file name
|
yuuji@0
|
200 * Accepts: return buffer for file name
|
yuuji@0
|
201 * file name
|
yuuji@0
|
202 * locking to be placed on file if non-NIL
|
yuuji@0
|
203 * Returns: file descriptor of lock or -1 if error
|
yuuji@0
|
204 */
|
yuuji@0
|
205
|
yuuji@0
|
206 int lockname (char *lock,char *fname,int op)
|
yuuji@0
|
207 {
|
yuuji@0
|
208 int ld;
|
yuuji@0
|
209 char c,*s;
|
yuuji@0
|
210 if (!((s = lockdir (lock,getenv ("TEMP"),NIL)) ||
|
yuuji@0
|
211 (s = lockdir (lock,getenv ("TMP"),NIL)) ||
|
yuuji@0
|
212 (s = lockdir (lock,getenv ("TMPDIR"),NIL)) ||
|
yuuji@0
|
213 /* C:\TEMP is last resort */
|
yuuji@0
|
214 (s = lockdir (lock,defaultDrive (),"TEMP")))) {
|
yuuji@0
|
215 mm_log ("Unable to find temporary directory",ERROR);
|
yuuji@0
|
216 return -1;
|
yuuji@0
|
217 }
|
yuuji@0
|
218 /* generate file name */
|
yuuji@0
|
219 while (c = *fname++) switch (c) {
|
yuuji@0
|
220 case '/': case '\\': case ':':
|
yuuji@0
|
221 *s++ = '!'; /* convert bad chars to ! */
|
yuuji@0
|
222 break;
|
yuuji@0
|
223 default:
|
yuuji@0
|
224 *s++ = c;
|
yuuji@0
|
225 break;
|
yuuji@0
|
226 }
|
yuuji@0
|
227 *s++ = c; /* tie off name */
|
yuuji@0
|
228 /* get the lock */
|
yuuji@0
|
229 if (((ld = open (lock,O_BINARY|O_RDWR|O_CREAT,S_IREAD|S_IWRITE)) >= 0) && op)
|
yuuji@0
|
230 flock (ld,op); /* apply locking function */
|
yuuji@0
|
231 return ld; /* return locking file descriptor */
|
yuuji@0
|
232 }
|
yuuji@0
|
233
|
yuuji@0
|
234 /* Build lock directory, check to see if it exists
|
yuuji@0
|
235 * Accepts: return buffer for lock directory
|
yuuji@0
|
236 * first part of possible name
|
yuuji@0
|
237 * optional second part
|
yuuji@0
|
238 * Returns: pointer to end of buffer if buffer has a good name, else NIL
|
yuuji@0
|
239 */
|
yuuji@0
|
240
|
yuuji@0
|
241 char *lockdir (char *lock,char *first,char *last)
|
yuuji@0
|
242 {
|
yuuji@0
|
243 struct stat sbuf;
|
yuuji@0
|
244 char c,*s;
|
yuuji@0
|
245 if (first && *first) { /* first part must be non-NIL */
|
yuuji@0
|
246 /* copy first part */
|
yuuji@0
|
247 for (s = lock; *first; c = *s++ = *first++);
|
yuuji@0
|
248 if (last && *last) { /* copy last part if specified */
|
yuuji@0
|
249 /* write trailing \ in case not in first */
|
yuuji@0
|
250 if (c != '\\') *s++ = '\\';
|
yuuji@0
|
251 while (*last) c = *s++ = *last++;
|
yuuji@0
|
252 }
|
yuuji@0
|
253 if (c == '\\') --s; /* delete trailing \ if any */
|
yuuji@0
|
254 *s = '\0'; /* tie off name at this point */
|
yuuji@0
|
255 return stat (lock,&sbuf) ? NIL : s;
|
yuuji@0
|
256 }
|
yuuji@0
|
257 return NIL; /* failed */
|
yuuji@0
|
258 }
|
yuuji@0
|
259
|
yuuji@0
|
260
|
yuuji@0
|
261 /* Unlock file descriptor
|
yuuji@0
|
262 * Accepts: file descriptor
|
yuuji@0
|
263 * lock file name from lockfd()
|
yuuji@0
|
264 */
|
yuuji@0
|
265
|
yuuji@0
|
266 void unlockfd (int fd,char *lock)
|
yuuji@0
|
267 {
|
yuuji@0
|
268 flock (fd,LOCK_UN); /* unlock it */
|
yuuji@0
|
269 close (fd); /* close it */
|
yuuji@0
|
270 }
|
yuuji@0
|
271
|
yuuji@0
|
272
|
yuuji@0
|
273 /* Determine default prototype stream to user
|
yuuji@0
|
274 * Accepts: type (NIL for create, T for append)
|
yuuji@0
|
275 * Returns: default prototype stream
|
yuuji@0
|
276 */
|
yuuji@0
|
277
|
yuuji@0
|
278 MAILSTREAM *default_proto (long type)
|
yuuji@0
|
279 {
|
yuuji@0
|
280 extern MAILSTREAM DEFAULTPROTO;
|
yuuji@0
|
281 return &DEFAULTPROTO; /* return default driver's prototype */
|
yuuji@0
|
282 }
|
yuuji@0
|
283
|
yuuji@0
|
284 /* Global data */
|
yuuji@0
|
285
|
yuuji@0
|
286 static unsigned rndm = 0; /* initial `random' number */
|
yuuji@0
|
287
|
yuuji@0
|
288
|
yuuji@0
|
289 /* Return random number
|
yuuji@0
|
290 */
|
yuuji@0
|
291
|
yuuji@0
|
292 long random ()
|
yuuji@0
|
293 {
|
yuuji@0
|
294 if (!rndm) srand (rndm = (unsigned) time (0L));
|
yuuji@0
|
295 return (long) rand ();
|
yuuji@0
|
296 }
|
yuuji@0
|
297
|
yuuji@0
|
298
|
yuuji@0
|
299 /* Emulator for BSD syslog() routine
|
yuuji@0
|
300 * Accepts: priority
|
yuuji@0
|
301 * message
|
yuuji@0
|
302 * parameters
|
yuuji@0
|
303 */
|
yuuji@0
|
304
|
yuuji@0
|
305 void syslog (int priority,const char *message,...)
|
yuuji@0
|
306 {
|
yuuji@0
|
307 }
|
yuuji@0
|
308
|
yuuji@0
|
309
|
yuuji@0
|
310 /* Emulator for BSD openlog() routine
|
yuuji@0
|
311 * Accepts: identity
|
yuuji@0
|
312 * options
|
yuuji@0
|
313 * facility
|
yuuji@0
|
314 */
|
yuuji@0
|
315
|
yuuji@0
|
316 void openlog (const char *ident,int logopt,int facility)
|
yuuji@0
|
317 {
|
yuuji@0
|
318 }
|