imapext-2007

diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/osdep/nt/yunchan.c	Mon Sep 14 15:17:45 2009 +0900
     1.3 @@ -0,0 +1,286 @@
     1.4 +/* ========================================================================
     1.5 + * Copyright 1988-2006 University of Washington
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * 
    1.14 + * ========================================================================
    1.15 + */
    1.16 +
    1.17 +/*
    1.18 + * Program:	Unix compatibility routines
    1.19 + *
    1.20 + * Author:	Mark Crispin
    1.21 + *		Networks and Distributed Computing
    1.22 + *		Computing & Communications
    1.23 + *		University of Washington
    1.24 + *		Administration Building, AG-44
    1.25 + *		Seattle, WA  98195
    1.26 + *		Internet: MRC@CAC.Washington.EDU
    1.27 + *
    1.28 + * Date:	14 September 1996
    1.29 + * Last Edited:	30 August 2006
    1.30 + */
    1.31 +
    1.32 +
    1.33 +/*				DEDICATION
    1.34 + *
    1.35 + *  This file is dedicated to my dog, Unix, also known as Yun-chan and
    1.36 + * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast.  Unix
    1.37 + * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
    1.38 + * a two-month bout with cirrhosis of the liver.
    1.39 + *
    1.40 + *  He was a dear friend, and I miss him terribly.
    1.41 + *
    1.42 + *  Lift a leg, Yunie.  Luv ya forever!!!!
    1.43 + */
    1.44 + 
    1.45 +/* Emulator for BSD flock() call
    1.46 + * Accepts: file descriptor
    1.47 + *	    operation bitmask
    1.48 + * Returns: 0 if successful, -1 if failure
    1.49 + */
    1.50 +
    1.51 +/*  Our friends in Redmond have decided that you can not write to any segment
    1.52 + * which has a shared lock.  This screws up the shared-write mailbox drivers
    1.53 + * (mbx, mtx, and tenex).  As a workaround, we'll only lock the first byte of
    1.54 + * the file, meaning that you can't write that byte shared.
    1.55 + *  This behavior seems to be new as of NT 4.0.
    1.56 + */
    1.57 +
    1.58 +int flock (int fd,int op)
    1.59 +{
    1.60 +  HANDLE hdl = (HANDLE) _get_osfhandle (fd);
    1.61 +  DWORD flags = (op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0;
    1.62 +  OVERLAPPED offset = {NIL,NIL,0,0,NIL};
    1.63 +  int ret = -1;
    1.64 +  blocknotify_t bn = (blocknotify_t) 
    1.65 +    ((op & LOCK_NB) ? NIL : mail_parameters (NIL,GET_BLOCKNOTIFY,NIL));
    1.66 +  if (hdl < 0) errno = EBADF;	/* error in file descriptor */
    1.67 +  else switch (op & ~LOCK_NB) {	/* translate to LockFileEx() op */
    1.68 +  case LOCK_EX:			/* exclusive */
    1.69 +    flags |= LOCKFILE_EXCLUSIVE_LOCK;
    1.70 +  case LOCK_SH:			/* shared */
    1.71 +    if (!check_nt ()) return 0;	/* always succeeds if not NT */
    1.72 +    if (bn) (*bn) (BLOCK_FILELOCK,NIL);
    1.73 +				/* bug for bug compatible with Unix */
    1.74 +    UnlockFileEx (hdl,NIL,1,0,&offset);
    1.75 +				/* lock the file as requested */
    1.76 +    if (LockFileEx (hdl,flags,NIL,1,0,&offset)) ret = 0;
    1.77 +    if (bn) (*bn) (BLOCK_NONE,NIL);
    1.78 +				/* if failed */
    1.79 +    if (ret) errno = (op & LOCK_NB) ? EAGAIN : EBADF;
    1.80 +    break;
    1.81 +  case LOCK_UN:			/* unlock */
    1.82 +    if (check_nt ()) UnlockFileEx (hdl,NIL,1,0,&offset);
    1.83 +    ret = 0;			/* always succeeds */
    1.84 +  default:			/* default */
    1.85 +    errno = EINVAL;		/* bad call */
    1.86 +    break;
    1.87 +  }
    1.88 +  return ret;
    1.89 +}
    1.90 +
    1.91 +/* Local storage */
    1.92 +
    1.93 +static char *loghdr;		/* log file header string */
    1.94 +static HANDLE loghdl = NIL;	/* handle of event source */
    1.95 +
    1.96 +/* Emulator for BSD syslog() routine
    1.97 + * Accepts: priority
    1.98 + *	    message
    1.99 + *	    parameters
   1.100 + */
   1.101 +
   1.102 +void syslog (int priority,const char *message,...)
   1.103 +{
   1.104 +  va_list args;
   1.105 +  LPTSTR strs[2];
   1.106 +  char tmp[MAILTMPLEN];		/* callers must be careful not to pop this */
   1.107 +  unsigned short etype;
   1.108 +  if (!check_nt ()) return;	/* no-op on non-NT system */
   1.109 +				/* default event source */
   1.110 +  if (!loghdl) openlog ("c-client",LOG_PID,LOG_MAIL);
   1.111 +  switch (priority) {		/* translate UNIX type into NT type */
   1.112 +  case LOG_ALERT:
   1.113 +    etype = EVENTLOG_ERROR_TYPE;
   1.114 +    break;
   1.115 +  case LOG_INFO:
   1.116 +    etype = EVENTLOG_INFORMATION_TYPE;
   1.117 +    break;
   1.118 +  default:
   1.119 +    etype = EVENTLOG_WARNING_TYPE;
   1.120 +  }
   1.121 +  va_start (args,message);	/* initialize vararg mechanism */
   1.122 +  vsprintf (tmp,message,args);	/* build message */
   1.123 +  strs[0] = loghdr;		/* write header */
   1.124 +  strs[1] = tmp;		/* then the message */
   1.125 +				/* report the event */
   1.126 +  ReportEvent (loghdl,etype,(unsigned short) priority,2000,NIL,2,0,strs,NIL);
   1.127 +  va_end (args);
   1.128 +}
   1.129 +
   1.130 +
   1.131 +/* Emulator for BSD openlog() routine
   1.132 + * Accepts: identity
   1.133 + *	    options
   1.134 + *	    facility
   1.135 + */
   1.136 +
   1.137 +void openlog (const char *ident,int logopt,int facility)
   1.138 +{
   1.139 +  char tmp[MAILTMPLEN];
   1.140 +  if (!check_nt ()) return;	/* no-op on non-NT system */
   1.141 +  if (loghdl) fatal ("Duplicate openlog()!");
   1.142 +  loghdl = RegisterEventSource (NIL,ident);
   1.143 +  sprintf (tmp,(logopt & LOG_PID) ? "%s[%d]" : "%s",ident,getpid ());
   1.144 +  loghdr = cpystr (tmp);	/* save header for later */
   1.145 +}
   1.146 +
   1.147 +/* Copy Unix string with CRLF newlines
   1.148 + * Accepts: destination string
   1.149 + *	    pointer to size of destination string buffer
   1.150 + *	    source string
   1.151 + *	    length of source string
   1.152 + * Returns: length of copied string
   1.153 + */
   1.154 +
   1.155 +unsigned long unix_crlfcpy (char **dst,unsigned long *dstl,char *src,
   1.156 +			    unsigned long srcl)
   1.157 +{
   1.158 +  unsigned long i,j;
   1.159 +  char *d = src;
   1.160 +				/* count number of LF's in source string(s) */
   1.161 +  for (i = srcl,j = 0; j < srcl; j++) if (*d++ == '\012') i++;
   1.162 +				/* flush destination buffer if too small */
   1.163 +  if (*dst && (i > *dstl)) fs_give ((void **) dst);
   1.164 +  if (!*dst) {			/* make a new buffer if needed */
   1.165 +    *dst = (char *) fs_get ((*dstl = i) + 1);
   1.166 +    if (dstl) *dstl = i;	/* return new buffer length to main program */
   1.167 +  }
   1.168 +  d = *dst;			/* destination string */
   1.169 +				/* copy strings, inserting CR's before LF's */
   1.170 +  while (srcl--) switch (*src) {
   1.171 +  case '\015':			/* unlikely carriage return */
   1.172 +    *d++ = *src++;		/* copy it and any succeeding linefeed */
   1.173 +    if (srcl && *src == '\012') {
   1.174 +      *d++ = *src++;
   1.175 +      srcl--;
   1.176 +    }
   1.177 +    break;
   1.178 +  case '\012':			/* line feed? */
   1.179 +    *d++ ='\015';		/* yes, prepend a CR, drop into default case */
   1.180 +  default:			/* ordinary chararacter */
   1.181 +    *d++ = *src++;		/* just copy character */
   1.182 +    break;
   1.183 +  }
   1.184 +  *d = '\0';			/* tie off destination */
   1.185 +  return d - *dst;		/* return length */
   1.186 +}
   1.187 +
   1.188 +/* Length of Unix string after unix_crlfcpy applied
   1.189 + * Accepts: source string
   1.190 + * Returns: length of string
   1.191 + */
   1.192 +
   1.193 +unsigned long unix_crlflen (STRING *s)
   1.194 +{
   1.195 +  unsigned long pos = GETPOS (s);
   1.196 +  unsigned long i = SIZE (s);
   1.197 +  unsigned long j = i;
   1.198 +  while (j--) switch (SNX (s)) {/* search for newlines */
   1.199 +  case '\015':			/* unlikely carriage return */
   1.200 +    if (j && (CHR (s) == '\012')) {
   1.201 +      SNX (s);			/* eat the line feed */
   1.202 +      j--;
   1.203 +    }
   1.204 +    break;
   1.205 +  case '\012':			/* line feed? */
   1.206 +    i++;
   1.207 +  default:			/* ordinary chararacter */
   1.208 +    break;
   1.209 +  }
   1.210 +  SETPOS (s,pos);		/* restore old position */
   1.211 +  return i;
   1.212 +}
   1.213 +
   1.214 +/* Undoubtably, I'm going to regret these two routines in the future.  I
   1.215 + * regret them now.  Their purpose is to work around two problems in the
   1.216 + * VC++ 6.0 C library:
   1.217 + *  (1) tmpfile() creates the file in the current directory instead of a
   1.218 + *	temporary directory
   1.219 + *  (2) tmpfile() and fclose() think that on NT systems, it works to unlink
   1.220 + *	the file while it's still open, so there's no need for the _tmpfname
   1.221 + *	hook at fclose().  Unfortunately, that doesn't work in Win2K.
   1.222 + * I would be delighted to have a better alternative.
   1.223 + */
   1.224 +
   1.225 +#undef fclose			/* use the real fclose() in close_file() */
   1.226 +
   1.227 +/* Substitute for Microsoft's tmpfile() that uses the real temporary directory
   1.228 + * Returns: FILE structure if success, NIL if failure
   1.229 + */
   1.230 +
   1.231 +FILE *create_tempfile (void)
   1.232 +{
   1.233 +  FILE *ret = NIL;
   1.234 +  char *s = _tempnam (getenv ("TEMP"),"msg");
   1.235 +  if (s) {			/* if got temporary name... */
   1.236 +				/* open file, and stash name on _tmpfname */
   1.237 +    if (ret = fopen (s,"w+b")) ret->_tmpfname = s;
   1.238 +    else fs_give ((void **) &s);/* flush temporary string */
   1.239 +  }
   1.240 +  return ret;
   1.241 +}
   1.242 +
   1.243 +
   1.244 +/* Substitute for Microsoft's fclose() that always flushes _tmpfname
   1.245 + * Returns: FILE structure if success, NIL if failure
   1.246 + */
   1.247 +
   1.248 +int close_file (FILE *stream)
   1.249 +{
   1.250 +  int ret;
   1.251 +  char *s = stream->_tmpfname;
   1.252 +  stream->_tmpfname = NIL;	/* just in case fclose() tries to delete it */
   1.253 +  ret = fclose (stream);	/* close the file */
   1.254 +  if (s) {			/* was there a _tmpfname? */
   1.255 +    unlink (s);			/* yup, delete it */
   1.256 +    fs_give ((void **) &s);	/* and flush the name */
   1.257 +  }
   1.258 +  return ret;
   1.259 +}
   1.260 +
   1.261 +/* Get password from console
   1.262 + * Accepts: prompt
   1.263 + * Returns: password
   1.264 + */
   1.265 +
   1.266 +#define PWDLEN 128		/* used by Linux */
   1.267 +
   1.268 +char *getpass (const char *prompt)
   1.269 +{
   1.270 +  static char pwd[PWDLEN];
   1.271 +  int ch,i,done;
   1.272 +  fputs (prompt,stderr);	/* output prompt */
   1.273 +  for (i = done = 0; !done; ) switch (ch = _getch()) {
   1.274 +  case 0x03:			/* CTRL/C stops program */
   1.275 +    _exit (1);
   1.276 +  case '\b':			/* BACKSPACE erase previous character */
   1.277 +    if (i) pwd[--i] = '\0';
   1.278 +    break;
   1.279 +  case '\n': case '\r':		/* CR or LF terminates string */
   1.280 +    done = 1;
   1.281 +    break;
   1.282 +  default:			/* any other character is a pwd char */
   1.283 +    if (i < (PWDLEN - 1)) pwd[i++] = ch;
   1.284 +    break;
   1.285 +  }
   1.286 +  pwd[i] = '\0';		/* tie off string with null */
   1.287 +  putchar ('\n');		/* echo newline */
   1.288 +  return pwd;
   1.289 +}

UW-IMAP'd extensions by yuuji