2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * $TOG: funcs.C /main/16 1998/04/17 11:51:14 mgreess $
26 * Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
27 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
28 * States. Use of a copyright notice is precautionary only and does not
29 * imply publication or disclosure.
31 * This software contains confidential information and trade secrets of HaL
32 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
33 * without the prior express written permission of HaL Computer Systems, Inc.
35 * RESTRICTED RIGHTS LEGEND
36 * Use, duplication, or disclosure by the Government is subject to
37 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
38 * Technical Data and Computer Software clause at DFARS 252.227-7013.
39 * HaL Computer Systems, Inc.
40 * 1315 Dell Avenue, Campbell, CA 95008
46 #include "utility/funcs.h"
47 #include "unique_id.h"
49 #define X_INCLUDE_TIME_H
50 #define XOS_USE_XT_LOCKING
51 #include <X11/Xos_r.h>
53 /* Imake stuff defines SYSV; this code uses SVR4 ... here's the quick-fix */
54 #if defined(SYSV) && ! defined(SVR4)
59 #include <sys/utsname.h>
67 #include <sys/statfs.h>
68 #include <sys/statvfs.h>
70 #include <sys/statvfs.h>
77 int statvfs(const char *, struct statvfs *);
78 int getdomainname(char *, int);
87 int _DtMmdbStrcasecmp(register const char* s1, register const char* s2)
92 c1 = isupper(*s1) ? tolower(*s1) : *s1;
93 c2 = isupper(*s2) ? tolower(*s2) : *s2;
99 return (int) (*s1 - *s2);
102 int _DtMmdbStrncasecmp(register const char* s1,
103 register const char* s2,
112 c1 = isupper(*s1) ? tolower(*s1) : *s1;
113 c2 = isupper(*s2) ? tolower(*s2) : *s2;
114 if ((c1 != c2) || (! --count))
119 return (int) (*s1 - *s2);
125 #include <sys/utsname.h>
127 int gethostname(char* name, int namelen)
129 struct utsname myuname;
130 if ( uname(&myuname) != 0 ) {
131 MESSAGE(cerr, "gethostname(): uname() failed");
135 int l = strlen(myuname.nodename);
136 if ( l >= namelen ) {
137 cerr << "gethostname(): name array too short.\n";
140 memcpy(name, myuname.nodename, l);
146 int compare_stream(ostringstream& x, ostringstream& y)
148 string xstr = x.str();
149 string ystr = y.str();
151 if ( xstr.size() != ystr.size() ) {
152 cerr << xstr.size() << "---" << ystr.size() << endl;
153 //debug(cerr, xstr.c_str());
154 //debug(cerr, ystr.c_str());
158 char* u = (char *)xstr.c_str();
159 char* v = (char *)ystr.c_str();
163 //fprintf(stderr, "u=%s, pcount() = %d\n", u, x.pcount());
164 //fprintf(stderr, "v=%s, pcount() = %d\n", v, y.pcount());
166 if ( memcmp(u, v, xstr.size()) != 0 ) {
167 STDERR_MESSAGE("two streams do not match.");
172 //STDERR_MESSAGE("two streams match.");
179 float flog2(unsigned int x)
181 return (float)(log((double)x) / log((double)2));
184 float flog2(const float x)
186 return (float)log((double)x) / (float)log((float)2);
189 int pow2(const int x)
191 return (int)pow((double)2, (double)x);
194 int pow2(const float x)
196 return (int)pow((double)2, (double)x);
199 int bits(const int x)
201 return (int)flog2((unsigned int)x);
205 int pos_of_LSB(const unsigned int y)
209 case 8192: return 13;
210 case 1024: return 10;
217 //debug(cerr, hex(x));
220 for ( i =0; i<sizeof(x); i++ ) {
221 if ( ( 0x000000ff & x) == 0 )
230 for ( j =1; j<=8; j++ )
231 if ( (0x00000001 & x) == 0 )
237 //debug(cerr, i*8+j);
246 void char_swap(char& c1, char& c2)
253 void short_swap(short& c1, short& c2)
260 void int_swap(int& c1, int& c2)
268 int ceiling(const float x)
276 unsigned getbits(unsigned x, unsigned p, unsigned n)
278 return((x>> (p-n)) & ~(~0 << n));
281 int del_file(const char* filename, const char* pathname)
283 unsigned int len, slen;
284 static char buf[BUFLEN];
289 ok = unlink(filename);
292 if ( strlen(filename) + strlen(pathname) > (BUFLEN - 1) )
293 throw(boundaryException(1, BUFLEN,
294 strlen(filename) + strlen(pathname)));
297 len = MIN(strlen(pathname), BUFLEN - 1);
298 *((char *) memcpy(buf, pathname, len) + len) = '\0';
300 len = MIN(1, BUFLEN - 1 - slen);
301 *((char *) memcpy(buf + slen, "/", len) + len) = '\0';
303 len = MIN(strlen(filename), BUFLEN - 1 - slen);
304 *((char *) memcpy(buf + slen, filename, len) + len) = '\0';
309 debug(cerr, pathname);
310 debug(cerr, filename);
311 MESSAGE(cerr, form("unlink %s/%s failed", pathname, filename));
312 throw(systemException(errno));
318 Boolean copy_file(const char* source, const char* sink)
320 fstream in(source, ios::in);
321 fstream out(sink, ios::out);
327 while ( (c=in.get()) != EOF ) {
328 out.put((unsigned char)c);
340 copy_file(const char* path, const char* file,
341 const char* source_ext, const char* target_ext)
343 char source[PATHSIZ];
344 char target[PATHSIZ];
346 snprintf(source, sizeof(source), "%s/%s.%s", path, file, source_ext);
347 snprintf(target, sizeof(target), "%s/%s.%s", path, file, target_ext);
349 return copy_file(source, target) ;
353 Boolean exist_file(const char* filename, const char* pathname)
357 struct stat stat_info;
360 ok = stat(form("%s/%s", pathname, filename), &stat_info);
362 ok = stat( filename, &stat_info );
366 return S_ISREG(stat_info.st_mode) ? true : false ;
372 MESSAGE(cerr, "exist_file(): stat() failed. an exception");
373 throw(systemException(errno));
378 int check_file(istream& in, const char* msg)
383 cerr << c << " " << (int)c << " <---" << msg << "\n";
388 cat_file(const char* source1, const char* source2, const char* target)
391 MESSAGE(cerr, "in cat_file");
392 debug(cerr, source1);
393 debug(cerr, source2);
397 fstream in1(source1, ios::in);
398 fstream out(target, ios::out);
404 while ( in1.getline(buf, BUFSIZ) ) {
407 if ( in1.gcount() < BUFSIZ - 1 )
414 fstream in2(source2, ios::in);
419 while ( in2.getline(buf, BUFSIZ) ) {
422 if ( in2.gcount() < BUFSIZ - 1 )
430 return ( out.fail() ) ? false : true;
434 Boolean exist_dir(const char* pathname)
436 struct stat stat_info;
438 if ( stat( pathname, &stat_info ) == 0 )
439 return S_ISDIR(stat_info.st_mode) ? true : false ;
445 MESSAGE(cerr, "exist_dir() failed");
446 debug(cerr, pathname);
447 throw(systemException(errno));
451 Boolean check_and_create_dir(const char* path)
453 if ( exist_dir(path) == true )
456 const char* path_tail = path + 1; // skip the first '/'
459 // create the subdirecties
460 while ( path_tail[0] != 0 &&
461 ( slash_ptr = (char *)strchr(path_tail, '/') ) ) {
463 path_tail = slash_ptr + 1; // set for the next check
464 slash_ptr[0] = 0; // temp. set the slash to 0.
467 if ( exist_dir(path) == false ) {
468 if ( mkdir(path, 0777) != 0 ) {
470 slash_ptr[0] = '/'; //reset to '/'
472 MESSAGE(cerr, form( "mkdir failed on path %s", path));
473 throw(systemException(errno));
476 slash_ptr[0] = '/'; //reset to '/'
479 // create the full path
480 if ( mkdir(path, 0777) != 0 ) {
481 cerr << "mkdir failed on path " << path << "\n";
482 throw(systemException(errno));
489 int open_prot(int min, int def)
493 umask(prot = umask(0));
495 prot = min | (def & ~(prot & 0777));
502 return open_prot(0600,0666);
507 return open_prot(0700,0777);
510 Boolean int_eq(void* x, void* y)
512 if ( *(int*)x == *(int*)y )
518 Boolean int_ls(void* x, void* y)
520 if ( *(int*)x < *(int*)y )
528 int u = sizeof(void*);
530 return ( delta == 0 ) ? x : x + u - delta;
533 //Boolean fcntl_lock( int fd, lock_t lt )
535 // flock flock_record;
539 // flock_record.l_type = F_RDLCK;
542 // flock_record.l_type = F_WRLCK;
545 // perror("fcntl_lock(): unknown lock type");
549 ///****************************/
550 //// the entire file is locked
551 ///****************************/
552 // flock_record.l_whence = SEEK_SET,
553 // flock_record.l_start = 0;
554 // flock_record.l_len = 0;
556 // if ( fcntl(fd, F_SETLKW, (int)&flock_record) != -1 ) {
563 //Boolean fcntl_unlock( int fd )
565 // flock flock_record;
567 ///****************************/
568 //// the entire file is unlocked
569 ///****************************/
570 // flock_record.l_type = F_UNLCK;
571 // flock_record.l_whence = SEEK_SET;
572 // flock_record.l_start = 0;
573 // flock_record.l_len = 0;
575 // if ( fcntl(fd, F_SETLKW, (int)&flock_record) != -1 ) {
581 //static Boolean time_out;
583 //Boolean timed_lock(int fd, lock_t lt, int seconds)
585 // signal(SIGALRM, (SIG_PF)onalarm);
589 // while ( fcntl_lock(fd, lt) == false ) {
590 // switch ( errno ) {
593 // if ( time_out == true ) {
595 // MESSAGE(cerr, "time out after");
596 // debug(cerr, seconds);
605 // MESSAGE(cerr, "error in fcntl_lock()");
612 // signal(SIGALRM, SIG_IGN);
616 //Boolean timed_unlock(int fd, int seconds)
618 // signal(SIGALRM, (SIG_PF)onalarm);
622 // while ( fcntl_unlock(fd) == false ) {
623 // switch ( errno ) {
626 // if ( time_out == true )
635 // signal(SIGALRM, SIG_IGN);
645 char* time_stamp(_Xctimeparams *ctime_buf)
649 return _XCtime(&x, *ctime_buf);
653 int bytes(fstream& fs)
655 struct stat file_info;
657 if ( fstat( fs.rdbuf() -> fd(), &file_info) != 0 )
660 return int(file_info.st_size);
665 struct stat file_info;
667 if ( fstat( fd, &file_info) != 0 )
670 return int(file_info.st_size);
673 int bytes(fstream* fs)
675 streampos begin, current, end;
678 current = fs->tellg();
684 total_bytes = end - begin;
685 return int(total_bytes);
689 int bytes(char * file_name)
691 struct stat file_info;
693 if ( stat( file_name, &file_info) != 0 )
696 return int(file_info.st_size);
699 char* form(const char* fmt, ...)
701 static char formbuf[BUFSIZ];
702 char tempbuf[BUFSIZ];
708 len = MIN(strlen(formbuf), BUFSIZ - 1);
709 *((char *) memcpy(tempbuf, formbuf, len) + len) = '\0';
710 (void) vsnprintf(tempbuf, sizeof(tempbuf), fmt, args);
714 len = MIN(strlen(tempbuf), BUFSIZ - 1);
715 *((char *) memcpy(formbuf, tempbuf, len) + len) = '\0';
719 static char info_buf[BUFSIZ];
721 char* access_info( char* request )
724 char dm_name[PATHSIZ];
725 int dm_name_sz = PATHSIZ;
727 if ( getdomainname(dm_name, dm_name_sz) == -1 ) {
728 MESSAGE(cerr, "getdomainname() failed");
729 throw(systemException(errno));
734 struct utsname name ;
737 char host_name[PATHSIZ];
738 int host_name_sz = PATHSIZ;
739 if ( gethostname(host_name, host_name_sz) == -1 ) {
740 MESSAGE(cerr, "gethostname() failed");
741 throw(systemException(errno));
745 _Xctimeparams ctime_buf;
746 char* x = time_stamp(&ctime_buf);
750 snprintf(info_buf, sizeof(info_buf), "%s-%s-%ld-%s-%s",
752 /* getenv("USER"), */
753 (long)getpid(), x, request
756 char userid[L_cuserid];
757 snprintf(info_buf, sizeof(info_buf), "%s-%s-%ld-%s-%s",
759 ( cuserid(userid)[0] == 0 ) ? "???" : userid,
760 /* getenv("USER"), */
761 (long)getpid(), x, request
768 void lsb_putbits(unsigned& target, unsigned position_from_lsb,
769 unsigned bits, unsigned source)
771 target |= ((source & ~( ~0 << bits )) << position_from_lsb) ;
774 unsigned lsb_getbits(unsigned source, unsigned position_from_lsb, unsigned bits)
776 return ( ( source >> position_from_lsb ) & ~( ~0 << bits ) );
779 Boolean cc_is_digit(istream& in)
785 return ( ok ) ? true : false;
788 unsigned long disk_space(const char* path)
790 #if defined(__osf__) || defined (hpux) || defined (SVR4) || defined(CSRG_BASED)
791 struct statvfs statfs_buf;
793 struct statfs statfs_buf;
798 #if defined(__osf__) || defined (hpux) || defined (SVR4) || defined(CSRG_BASED)
799 if ( statvfs(path, &statfs_buf) == 0 ) {
800 free_bytes = statfs_buf.f_bavail * statfs_buf.f_frsize ;
802 if ( statfs(path, &statfs_buf) == 0 ) {
803 free_bytes = statfs_buf.f_bavail * statfs_buf.f_bsize ;
807 throw(stringException(form("statfs failed on %s", path)));
813 Boolean writeToTmpFile(char* unique_nm, char* str, int size)
817 char* tmp_dir_tbl[4];
819 tmp_dir_tbl[0] = getenv("TMPDIR");
820 tmp_dir_tbl[1] = (char*)"/tmp";
821 tmp_dir_tbl[2] = (char*)"/usr/tmp";
822 tmp_dir_tbl[3] = getenv("HOME");
824 int tmp_dir_tbl_size = 4;
826 const char* uid = unique_id();
828 for ( int i=0; i<tmp_dir_tbl_size; i++ ) {
830 if ( tmp_dir_tbl[i] == 0 )
833 len = MIN(strlen(tmp_dir_tbl[i]) + strlen(uid) + 5, PATHSIZ - 1);
834 *((char *) memcpy(unique_nm,
835 form("%s/tmp.%s", tmp_dir_tbl[i], uid),
839 //debug(cerr, tmp_dir_tbl[i]);
840 //debug(cerr, disk_space(tmp_dir_tbl[i]));
841 if ( disk_space(tmp_dir_tbl[i]) <= (unsigned long) size )
844 out = new fstream(unique_nm, ios::out);
851 if ( ! (out->write(str, size) ) ) {