12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- *+SNOTICE
- *
- *
- * $TOG: IO.C /main/33 1999/01/29 14:45:00 mgreess $
- *
- * RESTRICTED CONFIDENTIAL INFORMATION:
- *
- * The information in this document is subject to special
- * restrictions in a confidential disclosure agreement bertween
- * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
- * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
- * Sun's specific written approval. This documment and all copies
- * and derivative works thereof must be returned or destroyed at
- * Sun's request.
- *
- * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
- *
- *+ENOTICE
- */
- #define X_INCLUDE_TIME_H
- #define X_INCLUDE_GRP_H
- #define X_INCLUDE_PWD_H
- #define XOS_USE_NO_LOCKING
- #include <X11/Xos_r.h>
- #include <assert.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdlib.h>
- //
- // START Order dependent for AIX
- //
- #include <sys/socket.h>
- #if defined(_aix)
- #include <sys/socketvar.h>
- #if defined(BIG_ENDIAN)
- #undef BIG_ENDIAN
- #endif
- #endif
- #include <netinet/in.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- //
- // END Order dependent for AIX
- //
- #include <sys/stat.h>
- #if !defined(__linux__)
- # include <sys/statvfs.h>
- #endif
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/uio.h>
- #include <unistd.h>
- #ifdef _AIX
- #include <sys/mntctl.h>
- #include <sys/statfs.h>
- #include <sys/vfs.h>
- #define IOVMAX MSG_MAXIOVLEN
- extern "C"
- {
- fchmod(int, mode_t);
- statfs(const char *, struct statfs *);
- mntctl(int, int, char *);
- ssize_t writev(int, const struct iovec *, int);
- }
- #if (OSMAJORVERSION==4) && (OSMINORVERSION==2)
- /* Temporary hack till the /usr/lpp/xlC/include/unistd.h file is fixed. */
- extern "C" { int lockf(int, int, off_t); }
- #endif
- #endif /* _AIX */
- #include <DtMail/DtMail.hh>
- #include <DtMail/DtMailError.hh>
- #include <DtMail/IO.hh>
- #include <DtMail/Threads.hh>
- #if !defined(IOV_MAX)
- #if !defined(__linux__)
- #include <sys/stream.h>
- #endif
- #if !defined(DEF_IOV_MAX)
- #define DEF_IOV_MAX 16
- #endif
- #define IOV_MAX DEF_IOV_MAX
- #endif
- #define IOVEC_IOVBASE_INCREMENTOR(iov, bytes) \
- ((caddr_t)((size_t)iov->iov_base+bytes))
- // The following I/O routines are wrappers for the normal routines,
- // but they deal with EINTR, and partial read/write situations.
- //
- //
- int
- SafeOpen(const char * path, int oflag, mode_t mode)
- {
- int status;
-
- do {
- status = open(path, oflag, mode);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeClose(int fd)
- {
- int status;
- do {
- status = close(fd);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeLink(const char * existingPath, const char * newPath)
- {
- int status;
- do {
- status = link(existingPath, newPath);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeRename(const char * oldPath, const char * newPath)
- {
- int status;
- do {
- status = rename(oldPath, newPath);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeRemove(const char *path)
- {
- int status;
- do {
- status = remove(path);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeUnlink(const char *path)
- {
- int status;
- do {
- status = unlink(path);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- ssize_t
- SafeRead(int fd, void * buf, size_t bytes)
- {
- ssize_t status = 0;
- do {
- status = read(fd, buf, bytes);
- } while(status < 0 && errno == EINTR);
- return(status);
- }
- ssize_t
- SafeWrite(int fd, const void * buf, size_t bytes)
- {
- ssize_t status = 0;
- do {
- status = write(fd, buf, bytes);
- } while(status < 0 && errno == EINTR);
-
- return(status);
- }
- // SafeWritev -- safe multiply vectored write
- // Description:
- // SafeWritev provides an interrupt safe way to call the writev() system
- // call. In addition, it removes the IOV_MAX limitation on the size of the
- // iovec structure, and it will not return until either all bytes specified
- // by the iovec structure are written or writev() returns an error.
- // Arguments:
- // int fd -- file descriptor to write to
- // struct iovec *iov -- iovec structure describing writes to be done
- // int iovcnt -- number of elements in passed in iov structure
- // Outputs:
- // Will effectively destroy the contents of the passed in iovec structure.
- // The caller must deallocate the storage associated with the structure
- // upon regaining control.
- // Returns:
- // == -1 : error returned from writev() - errno set to specific error number
- // != -1 : number of bytes actually written to the file
- unsigned long
- SafeWritev(int fd, struct iovec *iov, int iovcnt)
- {
- ssize_t status;
- unsigned long bytesWritten = 0;
- // outer loop: starting with the first write vector, as long as there is
- // at least one vector left to feed writev(), do so
- //
- for(int curIov = 0; curIov < iovcnt; ) {
- // inner loop: feed writev() allowing for interrupted system call
- do {
- status = writev(
- fd,
- &iov[curIov],
- (iovcnt-curIov) > IOV_MAX ? IOV_MAX : (iovcnt-curIov));
- } while (status < 0 && errno == EINTR);
- if (status == (ssize_t)-1) // true error from writev??
- return((unsigned long)-1); // yes: bail at this point to caller
- bytesWritten += status; // bump # bytes written count
- // must now "walk through" the io vector until we are up the to point
- // indicated by the number of bytes written by writev() - any leftover
- // in status indicates a partial write of a vector
- //
- while ((status > 0) && (curIov < iovcnt) && (iov[curIov].iov_len <= status)) {
- status -= iov[curIov++].iov_len;
- }
- // Check to see if we have reached the end of the io vector array; also
- // check to see if more bytes were written than called for; as crazy as
- // this sounds, in at least one instance when we finish spinning through
- // the io vectors we still had bytes left that had been written but not
- // accounted for in the io vectors (status > 0 && curIov >= iovcnt)
- //
- if (curIov >= iovcnt) { // out of IO vectors?
- if (status > 0) { // yes: all data accounted for?
- DtMailEnv error; // NO:: log error condition
- error.logError(
- DTM_TRUE,
- "SafeWritev: writev(): too many bytes written (%d/%d)\n",
- status, bytesWritten);
- }
- continue; // continue and let for loop exit
- }
-
- // Check for a partial write: if the current vector contains more data
- // than what has been written, writev() bailed in the middle of writing
- // a vector - adjust the vector and and feed it back to writev() again
- // OTHERWISE writev() ended with the current vector so move on to the next
- //
- if (iov[curIov].iov_len == status) // full write of this vector?
- curIov++; // yes: move on to the next vector
- else if (status != 0) { // no: adjust this vector and retry
- iov[curIov].iov_len -= status;
- iov[curIov].iov_base = IOVEC_IOVBASE_INCREMENTOR((&iov[curIov]), status);
- }
- }
- return(bytesWritten);
- }
- #define SWS_BUFFERSIZE 1024
- ssize_t
- SafeWriteStrip(int fd, const void * buf, size_t bytes)
- {
- ssize_t status = 0;
- int i, j;
- char *ptr = (char*)buf, *writebuf;
-
- // bug 5856: don't write out control M
- // make a finite size buffer for writing
- writebuf = (char*) malloc(bytes < SWS_BUFFERSIZE ? bytes : SWS_BUFFERSIZE);
- for (i = 0, j = 0; i < bytes; i++, ptr++) {
- if (*ptr == '\r' && *(ptr+1) == '\n')
- continue;
- writebuf[j++] = *ptr;
- if (j == SWS_BUFFERSIZE || i == (bytes-1)) {
- do {
- status = write(fd, writebuf, j);
- } while(status < 0 && errno == EINTR);
- j = 0;
- }
- }
- free(writebuf);
-
- return(status);
- }
- int
- SafeStat(const char * path, struct stat * buf)
- {
- int status;
- do {
- status = stat(path, buf);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeFchown(int fd, uid_t owner, gid_t group)
- {
- int status;
- do {
- status = fchown(fd, owner, group);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeLStat(const char * path, struct stat * buf)
- {
- int status;
- do {
- status = lstat(path, buf);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeFStat(int fd, struct stat * buf)
- {
- int status;
- do {
- status = fstat(fd, buf);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- // SafeGuaranteedStat - return stat info for object given path name
- // If NFS attribute caching is enabled (which is the default), a
- // stat/fstat of a NFS file may not return the correct true size of the
- // mailbox if it has been appended to since the last time it was read.
- // To get around this problem, this function will perform a open(),
- // read() of 1 byte, fstat(), close() which will force the attributes
- // for the named file to be retrieved directly from the server.
- //
- int
- SafeGuaranteedStat(const char * path, struct stat * buf)
- {
- int saveErrno;
- #ifndef O_RSYNC
- int tempFd = SafeOpen(path, O_RDONLY|O_SYNC);
- #else
- int tempFd = SafeOpen(path, O_RDONLY|O_RSYNC|O_SYNC);
- #endif /* O_RSYNC */
- if (tempFd == -1) {
- return(-1);
- }
- char tempBuf;
- if (SafeRead(tempFd, &tempBuf, 1) == -1) {
- saveErrno = errno;
- (void) SafeClose(tempFd);
- errno = saveErrno;
- return(-1);
- }
- if (SafeFStat(tempFd, buf) == -1) {
- saveErrno = errno;
- (void) SafeClose(tempFd);
- errno = saveErrno;
- return(-1);
- }
- (void) SafeClose(tempFd);
- return(0);
- }
- int
- SafeTruncate(const char * path, off_t len)
- {
- int status;
- do {
- status = truncate((char *)path, len); // The cast is for AIX
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeFTruncate(int fd, off_t len)
- {
- int status;
- do {
- status = ftruncate(fd, len);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeAccess(const char * path, int amode)
- {
- int status;
- do {
- status = access(path, amode);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- #if defined(sun)
- #define LOCKF_SIZE_TYPE long
- #else
- #define LOCKF_SIZE_TYPE off_t
- #endif
- int
- SafeLockf(int fd, int func, long size)
- {
- int status;
- do {
- status = lockf(fd, func, (LOCKF_SIZE_TYPE) size);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeFChmod(int fd, mode_t mode)
- {
- int status;
- do {
- status = fchmod(fd, mode);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeDup2(int fd1, int fd2)
- {
- int status;
- do {
- status = dup2(fd1, fd2);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeExecvp(const char * file, char *const *argv)
- {
- int status;
- do {
- status = execvp(file, (char * const *)argv);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- int
- SafeWaitpid(pid_t proc, int * p_stat, int options)
- {
- pid_t status;
- do {
- status = waitpid(proc, p_stat, options);
- } while (status < 0 && errno == EINTR);
- return((int)status);
- }
- int
- SafeWait(int * p_stat)
- {
- pid_t status;
- do {
- status = wait(p_stat);
- } while (status < 0 && errno == EINTR);
- return((int)status);
- }
- int
- SafeUTime(const char * path, utimbuf * ntime)
- {
- int status;
- do {
- status = utime(path, ntime);
- } while (status < 0 && errno == EINTR);
- return(status);
- }
- void
- SafePathIsAccessible(DtMailEnv &error, const char *path)
- {
- int status;
- status = SafeAccess(path, F_OK);
- if (-1 == status)
- {
- if (EACCES == errno)
- error.vSetError(DTME_PathElementPermissions, DTM_FALSE, NULL, path);
- else if (ENOTDIR == errno)
- error.vSetError(DTME_PathElementNotDirectory, DTM_FALSE, NULL, path);
- else if (ENOENT == errno)
- {
- char *s, *t;
- t = strdup(path);
- s = strrchr(t, '/');
- if (s && s != t)
- {
- *s = '\0';
- status = SafeAccess(t, F_OK);
- if (-1 == status)
- error.vSetError(
- DTME_PathElementDoesNotExist,
- DTM_FALSE, NULL,
- path);
- }
- }
- }
- }
- #if defined(POSIX_THREADS)
- static void * time_mutex = NULL;
- #endif
- void
- SafeCtime(const time_t *clock, char * buf, int buflen)
- {
- _Xctimeparams ctime_buf;
- char *result;
- memset((void*) &ctime_buf, 0, sizeof(_Xctimeparams));
- result = _XCtime(clock, ctime_buf);
- if (result)
- strncpy(buf, result, buflen);
- else
- *buf = '\0';
- }
- void
- SafeLocaltime(const time_t *clock, tm & result)
- {
- struct tm *time_ptr;
- _Xltimeparams localtime_buf;
- memset((void*) &localtime_buf, 0, sizeof(_Xltimeparams));
- time_ptr = _XLocaltime(clock, localtime_buf);
- result = *time_ptr;
- }
- time_t
- SafeMktime(tm * timeptr)
- {
- #if defined(POSIX_THREADS)
- if (!time_mutex) {
- time_mutex = MutexInit();
- }
- MutexLock lock_scope(time_mutex);
- #endif
- return(mktime(timeptr));
- }
- size_t
- SafeStrftime(char * buf, size_t buf_size,
- const char * format, const tm * timeptr)
- {
- #if defined(POSIX_THREADS)
- if (!time_mutex) {
- time_mutex = MutexInit();
- }
- MutexLock lock_scope(time_mutex);
- #endif
- return(strftime(buf, buf_size, format, timeptr));
- }
- #define SockINTERNAL_BUFSIZE 2048
- void *SockOpen(char *host, int clientPort, char **errorstring)
- {
- int sockfd;
- unsigned long inaddr;
- struct sockaddr_in ad;
- struct hostent *hp;
- DtMailEnv error;
- char *errorfmt = NULL;
- memset(&ad, 0, sizeof(ad));
- ad.sin_family = AF_INET;
- inaddr = inet_addr(host);
- if (inaddr != -1)
- memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
- else
- {
- hp = gethostbyname(host);
- if (hp == NULL)
- {
- if (NULL != errorstring)
- {
- errorfmt = DtMailEnv::getMessageText(
- SockErrorSet, 2,
- "Unknown host: %s");
- if (NULL == *errorstring) *errorstring = (char*) malloc(BUFSIZ);
- sprintf(*errorstring, errorfmt, host);
- }
- return (FILE*) NULL;
- }
- memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
- }
- ad.sin_port = htons(clientPort);
-
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0)
- {
- if (NULL != errorstring)
- {
- errorfmt = DtMailEnv::getMessageText(
- SockErrorSet, 3,
- "Error creating socket: %s");
- if (NULL == *errorstring) *errorstring = (char*) malloc(BUFSIZ);
- sprintf(*errorstring, errorfmt, error.errnoMessage());
- }
- return (FILE*) NULL;
- }
- if (connect(sockfd, (struct sockaddr *) &ad, sizeof(ad)) < 0)
- {
- if (NULL != errorstring)
- {
- errorfmt = DtMailEnv::getMessageText(
- SockErrorSet, 3,
- "Error connecting to socket: %s");
- if (NULL == *errorstring) *errorstring = (char*) malloc(BUFSIZ);
- sprintf(*errorstring, errorfmt, error.errnoMessage());
- }
- close(sockfd);
- return (FILE*) NULL;
- }
- #if defined(USE_SOCKSTREAM)
- FILE *sockfp = fdopen(sockfd, "r+");
- setvbuf(sockfp, NULL, _IONBF, SockINTERNAL_BUFSIZE);
- return (void*) sockfp;
- #else
- return (void*) sockfd;
- #endif
- }
- int SockPrintf(void *sockfp, char* format, ...)
- {
- va_list ap;
- char *buf = new char[8192];
- int i;
- va_start(ap, format);
- vsprintf(buf, format, ap);
- va_end(ap);
- i = SockWrite(buf, 1, strlen(buf), sockfp);
- delete [] buf;
- return i;
- }
- char *SockGets(char *buf, int len, void *sockfp)
- {
- #if defined(USE_SOCKSTREAM)
- char *in = fgets(buf, len, (FILE*) sockfp);
- fseek((FILE*) sockfp, 0L, SEEK_CUR); /* required by POSIX */
- return in;
- #else
- size_t n;
- char *bufp;
-
- n = 0;
- bufp = buf-1;
- do
- {
- bufp++;
- read((int) sockfp, (void*) bufp, 1);
- n++;
- } while (*bufp != '\n');
- *(bufp+1) = '\0';
- return buf;
- #endif
- }
- int SockRead(char *buf, int size, int len, void *sockfp)
- {
- #if defined(USE_SOCKSTREAM)
- int n = fread(buf, size, len, (FILE*) sockfp);
- fseek((FILE*) sockfp, 0L, SEEK_CUR); /* required by POSIX */
- #else
- int n = (int) read((int) sockfp, (void*) buf, (size_t) size * len);
- #endif
- return n;
- }
- int SockWrite(char *buf, int size, int len, void *sockfp)
- {
- int n;
- #if defined(USE_SOCKSTREAM)
- n = fwrite(buf, size, len, (FILE*) sockfp);
- fseek((FILE*) sockfp, 0L, SEEK_CUR); /* required by POSIX */
- #else
- n = write((int) sockfp, buf, size * len);
- #endif
- return n;
- }
- void SockClose(void *sockfp)
- {
- #if defined(USE_SOCKSTREAM)
- fclose((FILE*) sockfp);
- #else
- close((int) sockfp);
- #endif
- }
- void
- GetGroupName(char * grp_name)
- {
- struct group *grp;
- _Xgetgrparams grp_buf;
- memset((void*) &grp_buf, 0, sizeof(_Xgetgrparams));
- grp = _XGetgrgid(getegid(), grp_buf);
- if (grp) {
- strcpy(grp_name, grp->gr_name);
- }
- else {
- strcpy(grp_name, "UNKNOWN_GROUP");
- }
- }
- gid_t
- GetIdForGroupName(char * grp_name)
- {
- assert(grp_name != NULL);
- struct group *grp;
- _Xgetgrparams grp_buf;
-
- memset((void*) &grp_buf, 0, sizeof(_Xgetgrparams));
- grp = _XGetgrnam(grp_name, grp_buf);
-
- return(grp ? grp->gr_gid : (gid_t)-1);
- }
- void
- GetPasswordEntry(passwd & result)
- {
- static struct passwd passwordEntry;
- static int oneTimeFlag = 0;
- if (!oneTimeFlag) {
- _Xgetpwparams pw_buf;
- struct passwd *tresult;
- memset((void*) &pw_buf, 0, sizeof(_Xgetpwparams));
- #if defined(_AIX)
- _Xos_processLock;
- tresult = getpwuid(getuid());
- _Xos_processUnlock;
- #else
- tresult = _XGetpwuid(getuid(), pw_buf);
- #endif
- assert(tresult != NULL);
- memcpy(&passwordEntry, tresult, sizeof(struct passwd));
- passwordEntry.pw_name = strdup(passwordEntry.pw_name);
- passwordEntry.pw_passwd = strdup(passwordEntry.pw_passwd);
- #if !defined(_AIX) && !defined(__linux__) && !defined(CSRG_BASED)
- passwordEntry.pw_age = strdup(passwordEntry.pw_age);
- passwordEntry.pw_comment = strdup(passwordEntry.pw_comment);
- #endif
- passwordEntry.pw_gecos = strdup(passwordEntry.pw_gecos);
- passwordEntry.pw_dir = strdup(passwordEntry.pw_dir);
- passwordEntry.pw_shell = strdup(passwordEntry.pw_shell);
- oneTimeFlag++;
- }
- memcpy(&result, &passwordEntry, sizeof(struct passwd));
- return;
- }
- #if defined(MAILGROUP_REQUIRED)
- int isSetMailGidNeeded(const char * mailboxPath)
- {
- assert(mailboxPath);
- char inbox_path[1024];
- char mbox_path[1024];
- struct passwd *pw;
- struct stat buf;
- struct stat buf1;
- _Xgetpwparams pw_buf;
- memset((void*) &pw_buf, 0, sizeof(_Xgetpwparams));
- pw = _XGetpwuid(getuid(), pw_buf);
- // construct the lockfile name for the user.
- char *lock_file = (char *)calloc(1,strlen(pw->pw_name) + 6);
- strcpy(lock_file,pw->pw_name);
- strcat(lock_file,".lock");
- // parse the mailfolder name from the path
- char *p = strrchr(mailboxPath,'/');
- int len = (NULL!=0) ? strlen(mailboxPath)-strlen(p) : strlen(mailboxPath);
- char *str = (char *) calloc(1, len+1);
- strncpy(str, mailboxPath, len);
- str[len] = '\0';
-
- stat(str,&buf);
- // Default or system mailbox dir name.
- strcpy(inbox_path, "/var/spool/mail");
- stat(inbox_path,&buf1);
- free(str);
- if( ( (buf.st_dev == buf1.st_dev) && (buf.st_ino == buf1.st_ino) ) )
- {
- if( !strcmp((p+1),pw->pw_name) || !strcmp((p+1),lock_file) )
- {
- if( access(mailboxPath,R_OK) == -1 )
- {
- free(lock_file);
- return (1);
- }
- }
- free(lock_file);
- return ( 0 );
- }
- else
- {
- free(lock_file);
- return ( 1 );
- }
- }
- #endif
- #ifdef _AIX
- /*
- * NAME: get_stat
- *
- * FUNCTION:
- * gather mount status for all virtual mounts for this host.
- *
- * EXECUTION ENVIRONMENT: Part of user command.
- *
- * ON ENTRY:
- * vmountpp pointer to a buffer in which to put mount info
- *
- * NOTES:
- * get_stat() was lifted and slightly modified from
- * AIX Version 3 df.c.
- *
- * RETURNS:
- * < 0 error in mntctl()
- * > 0 for number of struct vmounts (mount points) in
- * buffer which is pointed to by pointer left at
- * *vmountpp.
- */
- int get_stat(
- struct vmount **vmountpp) /* place to tell where buffer is */
- {
- size_t size;
- struct vmount *vm;
- int nmounts;
- int count;
- size = BUFSIZ; /* initial default size */
- count = 10; /* don't try forever */
- while (count--) { /* don't try it forever */
- if ((vm = (struct vmount*) malloc(size)) == NULL) {
- return(-1);
- }
- /*
- * perform the QUERY mntctl - if it returns > 0, that is the
- * number of vmount structures in the buffer. If it returns
- * -1, an error occurred. If it returned 0, then look in
- * first word of buffer for needed size.
- */
- if ((nmounts = mntctl(MCTL_QUERY, size, (caddr_t)vm)) > 0) {
- *vmountpp = vm; /* OK, got it, now return */
- return(nmounts);
- } else {
- if (nmounts == 0) {
- size = *(int *)vm; /* the buffer wasn't big enough */
- free((void *)vm); /* get required buffer size */
- } else {
- free((void *)vm);/* some other kind of error occurred*/
- return(-1);
- }
- }
- }
- return(-1);
- }
- /*
- * NAME: get_vmount
- *
- * FUNCTION:
- * Determines, via the filesystems vmount structures,
- * the vmount id of the the filesystem id provided as
- * an argument (enables ultimate access to the actual
- * name of the filesystem).
- *
- * EXECUTION ENVIRONMENT: Part of user command.
- *
- * RETURNS:
- * ptr to structure with vmount id of filesystem or NULL
- */
- struct vmount *get_vmount(fsid_t *fsid)
- {
- struct vmount *inu_vmount_p=NULL;
- int inu_vmount_num;
- struct vmount *vm;
- int nmount;
- /* make sure we have all the virtual mount status of this host */
- if(inu_vmount_p == NULL)
- inu_vmount_num = get_stat(&inu_vmount_p);
- /* get the number of struct vmount in the vmount buffer */
- nmount = inu_vmount_num;
- /* go thru all the structures in the vmount buffer */
- for (vm = inu_vmount_p; nmount; nmount--,
- vm = (struct vmount *)((char *)vm + vm->vmt_length)) {
- if(( vm->vmt_fsid.fsid_dev == fsid->fsid_dev ) &&
- ( vm->vmt_fsid.fsid_type == fsid->fsid_type ))
- return(vm);
- }
- return((struct vmount *)NULL);
- }
- #endif /* _AIX */
- int FileSystemSpace(const char *file_path, size_t bytes, char **fsname)
- {
- int fserror=FALSE;
- struct stat stat_buf;
- size_t req_space = 0;
- #if !defined(__linux__)
- struct statvfs statvfs_buf;
- #endif
- if (stat(file_path,&stat_buf) < 0) return 0;
- #if !defined(__linux__)
- if (statvfs(file_path,&statvfs_buf) < 0) return 0;
- #endif
- #ifdef _AIX
- struct statfs statfs_buf;
- if (statfs(file_path,&statfs_buf) < 0) return 0;
- if (statfs_buf.f_vfstype == MNT_NFS)
- {
- struct vmount *vm;
- vm = get_vmount(&(statfs_buf.f_fsid));
- strcpy (statfs_buf.f_fname, vmt2dataptr (vm, VMT_STUB));
- }
- #endif /* _AIX */
- if (bytes != 0)
- {
- // The following code became redundant as the writeMailBox method now
- // checks for No space from the SafeWritev call.
- #if 0
- // CDExc20314
- // This check does not work (HP, IBM, Sun return -1; DEC returns 0)
- // Since the calling code has already created the file and is only
- // check that there is enough space, we don't need to check that
- // there are enough inodes.
- //
- // special case where the filesystem is out of inodes.
- if(statvfs_buf.f_ffree < 10) fserror = TRUE;
- #endif
- if (! fserror)
- {
- req_space = (size_t) ((bytes > stat_buf.st_size) ?
- (bytes-stat_buf.st_size) :
- 0);
- #if !defined(__linux__)
- if ( (statvfs_buf.f_bfree*statvfs_buf.f_bsize) >
- (req_space + statvfs_buf.f_bsize) )
- return 1;
- else
- fserror = TRUE;
- #endif
- }
- }
- else fserror = TRUE;
- if (fserror)
- {
- #ifdef _AIX
- *fsname = (char*) calloc(1, strlen(statfs_buf.f_fname)+1);
- strcpy (*fsname, statfs_buf.f_fname);
- #else
- *fsname = (char*) calloc(1, strlen(file_path)+1);
- strcpy (*fsname, file_path);
- #endif
- return 0;
- }
- return 1;
- }
|