imapext-2007

view src/osdep/nt/yunchan.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
line source
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 */
14 /*
15 * Program: Unix compatibility 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: 14 September 1996
26 * Last Edited: 30 August 2006
27 */
30 /* DEDICATION
31 *
32 * This file is dedicated to my dog, Unix, also known as Yun-chan and
33 * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix
34 * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
35 * a two-month bout with cirrhosis of the liver.
36 *
37 * He was a dear friend, and I miss him terribly.
38 *
39 * Lift a leg, Yunie. Luv ya forever!!!!
40 */
42 /* Emulator for BSD flock() call
43 * Accepts: file descriptor
44 * operation bitmask
45 * Returns: 0 if successful, -1 if failure
46 */
48 /* Our friends in Redmond have decided that you can not write to any segment
49 * which has a shared lock. This screws up the shared-write mailbox drivers
50 * (mbx, mtx, and tenex). As a workaround, we'll only lock the first byte of
51 * the file, meaning that you can't write that byte shared.
52 * This behavior seems to be new as of NT 4.0.
53 */
55 int flock (int fd,int op)
56 {
57 HANDLE hdl = (HANDLE) _get_osfhandle (fd);
58 DWORD flags = (op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0;
59 OVERLAPPED offset = {NIL,NIL,0,0,NIL};
60 int ret = -1;
61 blocknotify_t bn = (blocknotify_t)
62 ((op & LOCK_NB) ? NIL : mail_parameters (NIL,GET_BLOCKNOTIFY,NIL));
63 if (hdl < 0) errno = EBADF; /* error in file descriptor */
64 else switch (op & ~LOCK_NB) { /* translate to LockFileEx() op */
65 case LOCK_EX: /* exclusive */
66 flags |= LOCKFILE_EXCLUSIVE_LOCK;
67 case LOCK_SH: /* shared */
68 if (!check_nt ()) return 0; /* always succeeds if not NT */
69 if (bn) (*bn) (BLOCK_FILELOCK,NIL);
70 /* bug for bug compatible with Unix */
71 UnlockFileEx (hdl,NIL,1,0,&offset);
72 /* lock the file as requested */
73 if (LockFileEx (hdl,flags,NIL,1,0,&offset)) ret = 0;
74 if (bn) (*bn) (BLOCK_NONE,NIL);
75 /* if failed */
76 if (ret) errno = (op & LOCK_NB) ? EAGAIN : EBADF;
77 break;
78 case LOCK_UN: /* unlock */
79 if (check_nt ()) UnlockFileEx (hdl,NIL,1,0,&offset);
80 ret = 0; /* always succeeds */
81 default: /* default */
82 errno = EINVAL; /* bad call */
83 break;
84 }
85 return ret;
86 }
88 /* Local storage */
90 static char *loghdr; /* log file header string */
91 static HANDLE loghdl = NIL; /* handle of event source */
93 /* Emulator for BSD syslog() routine
94 * Accepts: priority
95 * message
96 * parameters
97 */
99 void syslog (int priority,const char *message,...)
100 {
101 va_list args;
102 LPTSTR strs[2];
103 char tmp[MAILTMPLEN]; /* callers must be careful not to pop this */
104 unsigned short etype;
105 if (!check_nt ()) return; /* no-op on non-NT system */
106 /* default event source */
107 if (!loghdl) openlog ("c-client",LOG_PID,LOG_MAIL);
108 switch (priority) { /* translate UNIX type into NT type */
109 case LOG_ALERT:
110 etype = EVENTLOG_ERROR_TYPE;
111 break;
112 case LOG_INFO:
113 etype = EVENTLOG_INFORMATION_TYPE;
114 break;
115 default:
116 etype = EVENTLOG_WARNING_TYPE;
117 }
118 va_start (args,message); /* initialize vararg mechanism */
119 vsprintf (tmp,message,args); /* build message */
120 strs[0] = loghdr; /* write header */
121 strs[1] = tmp; /* then the message */
122 /* report the event */
123 ReportEvent (loghdl,etype,(unsigned short) priority,2000,NIL,2,0,strs,NIL);
124 va_end (args);
125 }
128 /* Emulator for BSD openlog() routine
129 * Accepts: identity
130 * options
131 * facility
132 */
134 void openlog (const char *ident,int logopt,int facility)
135 {
136 char tmp[MAILTMPLEN];
137 if (!check_nt ()) return; /* no-op on non-NT system */
138 if (loghdl) fatal ("Duplicate openlog()!");
139 loghdl = RegisterEventSource (NIL,ident);
140 sprintf (tmp,(logopt & LOG_PID) ? "%s[%d]" : "%s",ident,getpid ());
141 loghdr = cpystr (tmp); /* save header for later */
142 }
144 /* Copy Unix string with CRLF newlines
145 * Accepts: destination string
146 * pointer to size of destination string buffer
147 * source string
148 * length of source string
149 * Returns: length of copied string
150 */
152 unsigned long unix_crlfcpy (char **dst,unsigned long *dstl,char *src,
153 unsigned long srcl)
154 {
155 unsigned long i,j;
156 char *d = src;
157 /* count number of LF's in source string(s) */
158 for (i = srcl,j = 0; j < srcl; j++) if (*d++ == '\012') i++;
159 /* flush destination buffer if too small */
160 if (*dst && (i > *dstl)) fs_give ((void **) dst);
161 if (!*dst) { /* make a new buffer if needed */
162 *dst = (char *) fs_get ((*dstl = i) + 1);
163 if (dstl) *dstl = i; /* return new buffer length to main program */
164 }
165 d = *dst; /* destination string */
166 /* copy strings, inserting CR's before LF's */
167 while (srcl--) switch (*src) {
168 case '\015': /* unlikely carriage return */
169 *d++ = *src++; /* copy it and any succeeding linefeed */
170 if (srcl && *src == '\012') {
171 *d++ = *src++;
172 srcl--;
173 }
174 break;
175 case '\012': /* line feed? */
176 *d++ ='\015'; /* yes, prepend a CR, drop into default case */
177 default: /* ordinary chararacter */
178 *d++ = *src++; /* just copy character */
179 break;
180 }
181 *d = '\0'; /* tie off destination */
182 return d - *dst; /* return length */
183 }
185 /* Length of Unix string after unix_crlfcpy applied
186 * Accepts: source string
187 * Returns: length of string
188 */
190 unsigned long unix_crlflen (STRING *s)
191 {
192 unsigned long pos = GETPOS (s);
193 unsigned long i = SIZE (s);
194 unsigned long j = i;
195 while (j--) switch (SNX (s)) {/* search for newlines */
196 case '\015': /* unlikely carriage return */
197 if (j && (CHR (s) == '\012')) {
198 SNX (s); /* eat the line feed */
199 j--;
200 }
201 break;
202 case '\012': /* line feed? */
203 i++;
204 default: /* ordinary chararacter */
205 break;
206 }
207 SETPOS (s,pos); /* restore old position */
208 return i;
209 }
211 /* Undoubtably, I'm going to regret these two routines in the future. I
212 * regret them now. Their purpose is to work around two problems in the
213 * VC++ 6.0 C library:
214 * (1) tmpfile() creates the file in the current directory instead of a
215 * temporary directory
216 * (2) tmpfile() and fclose() think that on NT systems, it works to unlink
217 * the file while it's still open, so there's no need for the _tmpfname
218 * hook at fclose(). Unfortunately, that doesn't work in Win2K.
219 * I would be delighted to have a better alternative.
220 */
222 #undef fclose /* use the real fclose() in close_file() */
224 /* Substitute for Microsoft's tmpfile() that uses the real temporary directory
225 * Returns: FILE structure if success, NIL if failure
226 */
228 FILE *create_tempfile (void)
229 {
230 FILE *ret = NIL;
231 char *s = _tempnam (getenv ("TEMP"),"msg");
232 if (s) { /* if got temporary name... */
233 /* open file, and stash name on _tmpfname */
234 if (ret = fopen (s,"w+b")) ret->_tmpfname = s;
235 else fs_give ((void **) &s);/* flush temporary string */
236 }
237 return ret;
238 }
241 /* Substitute for Microsoft's fclose() that always flushes _tmpfname
242 * Returns: FILE structure if success, NIL if failure
243 */
245 int close_file (FILE *stream)
246 {
247 int ret;
248 char *s = stream->_tmpfname;
249 stream->_tmpfname = NIL; /* just in case fclose() tries to delete it */
250 ret = fclose (stream); /* close the file */
251 if (s) { /* was there a _tmpfname? */
252 unlink (s); /* yup, delete it */
253 fs_give ((void **) &s); /* and flush the name */
254 }
255 return ret;
256 }
258 /* Get password from console
259 * Accepts: prompt
260 * Returns: password
261 */
263 #define PWDLEN 128 /* used by Linux */
265 char *getpass (const char *prompt)
266 {
267 static char pwd[PWDLEN];
268 int ch,i,done;
269 fputs (prompt,stderr); /* output prompt */
270 for (i = done = 0; !done; ) switch (ch = _getch()) {
271 case 0x03: /* CTRL/C stops program */
272 _exit (1);
273 case '\b': /* BACKSPACE erase previous character */
274 if (i) pwd[--i] = '\0';
275 break;
276 case '\n': case '\r': /* CR or LF terminates string */
277 done = 1;
278 break;
279 default: /* any other character is a pwd char */
280 if (i < (PWDLEN - 1)) pwd[i++] = ch;
281 break;
282 }
283 pwd[i] = '\0'; /* tie off string with null */
284 putchar ('\n'); /* echo newline */
285 return pwd;
286 }

UW-IMAP'd extensions by yuuji