~ubuntu-branches/debian/squeeze/alpine/squeeze

« back to all changes in this revision

Viewing changes to imap/src/osdep/nt/yunchan.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:     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
 */
 
28
 
 
29
 
 
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
 */
 
41
 
 
42
/* Emulator for BSD flock() call
 
43
 * Accepts: file descriptor
 
44
 *          operation bitmask
 
45
 * Returns: 0 if successful, -1 if failure
 
46
 */
 
47
 
 
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
 */
 
54
 
 
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
}
 
87
 
 
88
/* Local storage */
 
89
 
 
90
static char *loghdr;            /* log file header string */
 
91
static HANDLE loghdl = NIL;     /* handle of event source */
 
92
 
 
93
/* Emulator for BSD syslog() routine
 
94
 * Accepts: priority
 
95
 *          message
 
96
 *          parameters
 
97
 */
 
98
 
 
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
}
 
126
 
 
127
 
 
128
/* Emulator for BSD openlog() routine
 
129
 * Accepts: identity
 
130
 *          options
 
131
 *          facility
 
132
 */
 
133
 
 
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
}
 
143
 
 
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
 */
 
151
 
 
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
}
 
184
 
 
185
/* Length of Unix string after unix_crlfcpy applied
 
186
 * Accepts: source string
 
187
 * Returns: length of string
 
188
 */
 
189
 
 
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
}
 
210
 
 
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
 */
 
221
 
 
222
#undef fclose                   /* use the real fclose() in close_file() */
 
223
 
 
224
/* Substitute for Microsoft's tmpfile() that uses the real temporary directory
 
225
 * Returns: FILE structure if success, NIL if failure
 
226
 */
 
227
 
 
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
}
 
239
 
 
240
 
 
241
/* Substitute for Microsoft's fclose() that always flushes _tmpfname
 
242
 * Returns: FILE structure if success, NIL if failure
 
243
 */
 
244
 
 
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
}
 
257
 
 
258
/* Get password from console
 
259
 * Accepts: prompt
 
260
 * Returns: password
 
261
 */
 
262
 
 
263
#define PWDLEN 128              /* used by Linux */
 
264
 
 
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
}