Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / utility / funcs.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /*
24  * $TOG: funcs.C /main/16 1998/04/17 11:51:14 mgreess $
25  *
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.
30  * 
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.
34  * 
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
41  * 
42  */
43
44
45
46 #include "utility/funcs.h"
47 #include "unique_id.h"
48
49 #define X_INCLUDE_TIME_H
50 #define XOS_USE_XT_LOCKING
51 #include <X11/Xos_r.h>
52
53 /* Imake stuff defines SYSV; this code uses SVR4 ... here's the quick-fix */
54 #if defined(SYSV) && ! defined(SVR4)
55 #define SVR4
56 #endif
57
58 #ifdef SVR4
59 #include <sys/utsname.h>
60 #endif
61
62 #if defined(linux)
63 #include <sys/vfs.h>
64 #include <stdarg.h>
65 #elif defined(_AIX)
66 #include <sys/vfs.h>
67 #include <sys/statfs.h>
68 #include <sys/statvfs.h>
69 #else
70 #include <sys/statvfs.h>
71 #include <stdio.h>
72 #include <stdarg.h>
73 #endif
74 #ifdef __osf__
75 extern "C"
76 {
77 int statvfs(const char *, struct statvfs *);
78 int getdomainname(char *, int);
79 }
80 #endif /* __osf__ */
81 #include <sys/stat.h>
82
83 #define BUFLEN 512
84
85 #ifdef USL
86
87 int _DtMmdbStrcasecmp(register const char* s1, register const char* s2)
88 {
89     register int c1, c2;
90
91     while (*s1 && *s2) {
92         c1 = isupper(*s1) ? tolower(*s1) : *s1;
93         c2 = isupper(*s2) ? tolower(*s2) : *s2;
94         if (c1 != c2)
95             return (c1 - c2);
96         s1++;
97         s2++;
98     }
99     return (int) (*s1 - *s2);
100 }
101
102 int _DtMmdbStrncasecmp(register const char* s1,
103                        register const char* s2,
104                        register int count)
105 {
106     register int c1, c2;
107
108     if (!count)
109       return 0;
110
111     while (*s1 && *s2) {
112         c1 = isupper(*s1) ? tolower(*s1) : *s1;
113         c2 = isupper(*s2) ? tolower(*s2) : *s2;
114         if ((c1 != c2) || (! --count))
115             return (c1 - c2);
116         s1++;
117         s2++;
118     }
119     return (int) (*s1 - *s2);
120 }
121
122 #endif
123
124 #ifdef mips
125 #include <sys/utsname.h>
126
127 int gethostname(char* name, int namelen)
128 {
129    struct utsname myuname;
130    if ( uname(&myuname) != 0 ) {
131       MESSAGE(cerr, "gethostname(): uname() failed");
132       throw(Exception());
133    }
134
135    int l = strlen(myuname.nodename);
136    if ( l >= namelen ) {
137       cerr << "gethostname(): name array too short.\n";
138       throw(Exception());
139    } else
140       memcpy(name, myuname.nodename, l);
141    
142    return 0;
143 }
144 #endif
145
146 int compare_stream(ostringstream& x, ostringstream& y)
147 {
148    string xstr = x.str();
149    string ystr = y.str();
150
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());
155       return 1;
156    } else {
157
158      char* u = (char *)xstr.c_str();
159      char* v = (char *)ystr.c_str();
160
161 //debug(cerr, u);
162 //debug(cerr, v);
163 //fprintf(stderr, "u=%s, pcount() = %d\n", u, x.pcount());
164 //fprintf(stderr, "v=%s, pcount() = %d\n", v, y.pcount());
165
166      if ( memcmp(u, v, xstr.size()) != 0 ) {
167        STDERR_MESSAGE("two streams do not match.");
168 debug(cerr, u);
169 debug(cerr, v);
170        return 1;
171      } else {
172        //STDERR_MESSAGE("two streams match.");
173        return 0;
174      }
175    }
176 }
177
178 /*
179 float flog2(unsigned int x)
180 {
181    return (float)(log((double)x) / log((double)2));
182 }
183
184 float flog2(const float x)
185 {
186    return (float)log((double)x) / (float)log((float)2);
187 }
188
189 int pow2(const int x)
190 {
191    return (int)pow((double)2, (double)x);
192 }
193
194 int pow2(const float x)
195 {
196    return (int)pow((double)2, (double)x);
197 }
198
199 int bits(const int x)
200 {
201    return (int)flog2((unsigned int)x);
202 }
203 */
204
205 int pos_of_LSB(const unsigned int y)
206 {
207    switch (y) {
208
209    case 8192: return 13;
210    case 1024: return 10;
211
212    default:
213     {
214       unsigned int x = y;
215    
216    //debug(cerr, x);
217    //debug(cerr, hex(x));
218    
219       unsigned int i;
220       for ( i =0; i<sizeof(x); i++ ) {
221          if ( ( 0x000000ff & x) == 0 ) 
222             x >>= 8;
223          else
224             break;
225       }
226    
227    //debug(cerr, i);
228    
229       int j;
230       for ( j =1; j<=8; j++ )
231          if ( (0x00000001 & x) == 0 ) 
232             x >>= 1;
233          else
234             break;
235    
236    //debug(cerr, j);
237    //debug(cerr, i*8+j);
238    
239       return i*8 + j;
240      }
241    }
242    
243 }
244
245 /*
246 void char_swap(char& c1, char& c2)
247 {
248    char tmp = c1;
249    c1 = c2;
250    c2 = tmp;
251 }
252
253 void short_swap(short& c1, short& c2)
254 {
255    short tmp = c1;
256    c1 = c2;
257    c2 = tmp;
258 }
259
260 void int_swap(int& c1, int& c2)
261 {
262    int tmp = c1;
263    c1 = c2;
264    c2 = tmp;
265 }
266 */
267
268 int ceiling(const float x)
269 {
270    if ( int(x) > x )
271       return int(x)+1;
272    else
273       return int(x);
274 }
275
276 unsigned getbits(unsigned x, unsigned p, unsigned n)
277 {
278    return((x>> (p-n)) & ~(~0 << n));
279 }
280
281 int del_file(const char* filename, const char* pathname)
282 {
283    unsigned int len, slen;
284    static char buf[BUFLEN];
285
286    int ok;
287
288    if ( pathname == 0 )
289        ok = unlink(filename);
290    else {
291
292        if ( strlen(filename) + strlen(pathname) > (BUFLEN - 1) )
293           throw(boundaryException(1, BUFLEN,
294                                   strlen(filename) + strlen(pathname)));
295
296        buf[0] = 0;
297        len = MIN(strlen(pathname), BUFLEN - 1);
298        *((char *) memcpy(buf, pathname, len) + len) = '\0';
299        slen = len;
300        len = MIN(1, BUFLEN - 1 - slen);
301        *((char *) memcpy(buf + slen, "/", len) + len) = '\0';
302        slen += len;
303        len = MIN(strlen(filename), BUFLEN - 1 - slen);
304        *((char *) memcpy(buf + slen, filename, len) + len) = '\0';
305        ok = unlink(buf);
306    }
307    
308    if ( ok == -1 ) {
309       debug(cerr, pathname);
310       debug(cerr, filename);
311       MESSAGE(cerr, form("unlink %s/%s failed", pathname, filename));
312       throw(systemException(errno));
313    }
314
315    return 0;
316 }
317
318 Boolean copy_file(const char* source, const char* sink)
319 {
320    fstream in(source, ios::in);
321    fstream out(sink, ios::out);
322
323    if ( !in || ! out )
324       return false;
325
326    int c;
327    while ( (c=in.get()) != EOF ) {
328      out.put((unsigned char)c);
329    }
330
331    in.close();
332
333    if ( out.fail() ) 
334       return false;
335    else
336       return true;
337 }
338
339 Boolean
340 copy_file(const char* path, const char* file,
341           const char* source_ext, const char* target_ext)
342 {
343    char source[PATHSIZ];
344    char target[PATHSIZ];
345
346    snprintf(source, sizeof(source), "%s/%s.%s", path, file, source_ext);
347    snprintf(target, sizeof(target), "%s/%s.%s", path, file, target_ext);
348
349    return copy_file(source, target) ;
350 }
351
352
353 Boolean exist_file(const char* filename, const char* pathname)
354 {
355    int ok;
356
357    struct stat stat_info;
358
359     if ( pathname ) 
360        ok = stat(form("%s/%s", pathname, filename), &stat_info);
361     else
362        ok = stat( filename, &stat_info );
363
364
365     if ( ok == 0 )
366        return S_ISREG(stat_info.st_mode) ? true : false ;
367
368     switch (errno) {
369        case ENOENT: 
370           return false;
371        default: 
372           MESSAGE(cerr, "exist_file(): stat() failed. an exception");
373           throw(systemException(errno));
374     }
375
376 }
377
378 int check_file(istream& in, const char* msg)
379 {
380    char c;
381    in.get(c);
382    in.putback(c);
383    cerr << c << " " << (int)c << " <---" << msg << "\n";
384    return 0;
385 }
386
387 Boolean
388 cat_file(const char* source1, const char* source2, const char* target)
389 {
390 /*
391 MESSAGE(cerr, "in cat_file");
392 debug(cerr, source1);
393 debug(cerr, source2);
394 debug(cerr, target);
395 */
396
397    fstream in1(source1, ios::in);
398    fstream out(target, ios::out);
399
400    if ( !in1 || ! out )
401       return false;
402
403    char buf[BUFSIZ];
404    while ( in1.getline(buf, BUFSIZ) ) {
405      out << buf;
406
407      if ( in1.gcount() < BUFSIZ - 1 )
408         out << '\n';
409
410    }
411
412    in1.close();
413
414    fstream in2(source2, ios::in);
415
416    if ( !in2 )
417       return false;
418
419    while ( in2.getline(buf, BUFSIZ) ) {
420      out << buf;
421
422      if ( in2.gcount() < BUFSIZ - 1 )
423         out << '\n';
424
425    }
426
427    in2.close();
428    out.close();
429
430    return ( out.fail() ) ? false : true;
431 }
432
433
434 Boolean exist_dir(const char* pathname)
435 {
436    struct stat stat_info;
437
438    if ( stat( pathname, &stat_info ) == 0 ) 
439       return S_ISDIR(stat_info.st_mode) ? true : false ;
440
441    switch ( errno ) {
442       case ENOENT: 
443          return false;
444       default:
445          MESSAGE(cerr, "exist_dir() failed");
446          debug(cerr, pathname);
447          throw(systemException(errno));
448    }
449 }
450
451 Boolean check_and_create_dir(const char* path)
452 {
453    if ( exist_dir(path) == true )
454       return true;
455
456    const char* path_tail = path + 1; // skip the first '/'
457    char* slash_ptr;
458
459 // create the subdirecties
460    while ( path_tail[0] != 0 &&
461            ( slash_ptr = (char *)strchr(path_tail, '/') ) ) {
462
463        path_tail = slash_ptr + 1; // set for the next check
464        slash_ptr[0] = 0;          // temp. set the slash to 0.
465
466 //debug(cerr, path);
467        if ( exist_dir(path) == false ) {
468           if ( mkdir(path, 0777) != 0 ) {
469              debug(cerr, path);
470              slash_ptr[0] = '/';         //reset to '/'
471              perror(0);
472              MESSAGE(cerr, form( "mkdir failed on path %s", path));
473              throw(systemException(errno));
474           }
475        }
476        slash_ptr[0] = '/';         //reset to '/'
477    }
478
479 // create the full path
480    if ( mkdir(path, 0777) != 0 ) {
481       cerr << "mkdir failed on path " << path << "\n";
482       throw(systemException(errno));
483    } 
484
485    return true;
486 }
487
488 static
489 int open_prot(int min, int def)
490 {
491    int prot;
492
493    umask(prot = umask(0));
494
495    prot = min | (def & ~(prot & 0777));
496    
497    return prot;
498 }
499
500 int open_file_prot()
501 {
502    return open_prot(0600,0666);
503 }
504
505 int open_dir_prot()
506 {
507    return open_prot(0700,0777);
508 }
509
510 Boolean int_eq(void* x, void* y)
511 {
512    if ( *(int*)x == *(int*)y )
513        return true;
514    else
515        return false;
516 }
517
518 Boolean int_ls(void* x, void* y)
519 {
520    if ( *(int*)x < *(int*)y )
521        return true;
522    else
523        return false;
524 }
525
526 int ll4(int x)
527 {
528    int u = sizeof(void*);
529    int delta = x % u  ;
530    return ( delta == 0 ) ? x : x + u - delta;
531 }
532
533 //Boolean fcntl_lock( int fd, lock_t lt )
534 //{
535 //   flock flock_record;
536 //
537 //   switch ( lt ) {
538 //     case SHARED:
539 //         flock_record.l_type = F_RDLCK;
540 //         break;
541 //     case EXCLUSIVE:
542 //         flock_record.l_type = F_WRLCK;
543 //         break;
544 //     default:
545 //         perror("fcntl_lock(): unknown lock type");
546 //         exit(-2);
547 //   }
548 //
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;
555 //
556 //   if ( fcntl(fd, F_SETLKW, (int)&flock_record) != -1 ) {
557 //      return true;
558 //   } else {
559 //      return false;
560 //   }
561 //}
562 //      
563 //Boolean fcntl_unlock( int fd )
564 //{
565 //   flock flock_record;
566 //
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;
574 //
575 //   if ( fcntl(fd, F_SETLKW, (int)&flock_record) != -1 ) {
576 //      return true;
577 //   } else
578 //      return false;
579 //}
580 //
581 //static Boolean time_out;
582 //
583 //Boolean timed_lock(int fd, lock_t lt, int seconds)
584 //{
585 //   signal(SIGALRM, (SIG_PF)onalarm);
586 //   alarm(seconds);
587 //   time_out = false;
588 //
589 //   while ( fcntl_lock(fd, lt) == false ) {
590 //      switch ( errno ) {
591 //        case EINTR:
592 //
593 //           if ( time_out == true ) {
594 //#ifdef DEBUG
595 //              MESSAGE(cerr, "time out after");
596 //              debug(cerr, seconds);
597 //#endif
598 //              return false;
599 //           }
600 //
601 //           break;
602 //
603 //        default:
604 //#ifdef DEBUG
605 //           MESSAGE(cerr, "error in fcntl_lock()");
606 //           perror(0);
607 //           debug(cerr, fd);
608 //#endif
609 //           return false;
610 //      }
611 //   }
612 //   signal(SIGALRM, SIG_IGN);
613 //   return true;
614 //}
615 //
616 //Boolean timed_unlock(int fd, int seconds)
617 //{
618 //   signal(SIGALRM, (SIG_PF)onalarm);
619 //   alarm(seconds);
620 //   time_out = false;
621 //
622 //   while ( fcntl_unlock(fd) == false ) {
623 //      switch ( errno ) {
624 //        case EINTR:
625 //
626 //           if ( time_out == true )
627 //              return false;
628 //
629 //           break;
630 //
631 //        default:
632 //           return false;
633 //      }
634 //   }
635 //   signal(SIGALRM, SIG_IGN);
636 //   return true;
637 //}
638 //
639 //void onalarm(int)
640 //{
641 //   time_out = true;
642 //}
643
644 static
645 char* time_stamp(_Xctimeparams *ctime_buf)
646 {
647    time_t x;
648    time(&x);
649    return _XCtime(&x, *ctime_buf);
650 }
651
652 #ifdef C_API
653 int bytes(fstream& fs)
654 {
655    struct stat file_info;
656
657    if ( fstat( fs.rdbuf() -> fd(), &file_info) != 0 )
658       return 0;
659    else
660       return int(file_info.st_size);
661 }
662
663 int bytes(int fd)
664 {
665    struct stat file_info;
666
667    if ( fstat( fd, &file_info) != 0 )
668       return 0;
669    else
670       return int(file_info.st_size);
671 }
672 #else
673 int bytes(fstream* fs)
674 {
675    streampos begin, current, end;
676    int total_bytes;
677
678    current = fs->tellg();
679    fs->seekg(ios::beg);
680    begin = fs->tellg();
681    fs->seekg(ios::end);
682    end = fs->tellg();
683    fs->seekg(current);
684    total_bytes = end - begin;
685    return int(total_bytes);
686 }
687 #endif
688
689 int bytes(char * file_name)
690 {
691    struct stat file_info;
692
693    if ( stat( file_name, &file_info) != 0 )
694       return 0;
695    else
696       return int(file_info.st_size);
697 }
698
699 char* form(const char* fmt, ...)
700 {
701    static char formbuf[BUFSIZ];
702    char tempbuf[BUFSIZ];
703    va_list args;
704    int len;
705
706    va_start(args, fmt);
707
708    len = MIN(strlen(formbuf), BUFSIZ - 1);
709    *((char *) memcpy(tempbuf, formbuf, len) + len) = '\0';
710    (void) vsnprintf(tempbuf, sizeof(tempbuf), fmt, args);
711
712    va_end(args);
713
714    len = MIN(strlen(tempbuf), BUFSIZ - 1);
715    *((char *) memcpy(formbuf, tempbuf, len) + len) = '\0';
716    return formbuf;
717 }
718
719 static char info_buf[BUFSIZ];
720
721 char* access_info( char* request )
722 {
723 #ifndef SVR4
724    char dm_name[PATHSIZ];
725    int dm_name_sz = PATHSIZ;
726
727    if ( getdomainname(dm_name, dm_name_sz) == -1 ) {
728       MESSAGE(cerr, "getdomainname() failed");
729       throw(systemException(errno));
730    }
731 #endif
732
733 #ifdef SVR4
734    struct utsname name ;
735    uname(&name);
736 #else
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));
742    }
743 #endif
744
745    _Xctimeparams ctime_buf;
746    char* x = time_stamp(&ctime_buf);
747    x[strlen(x)-1] = 0;
748
749 #ifndef SVR4
750    snprintf(info_buf, sizeof(info_buf), "%s-%s-%ld-%s-%s",
751            host_name, dm_name,
752            /* getenv("USER"), */
753            (long)getpid(), x, request
754           );
755 #else
756    char userid[L_cuserid];
757    snprintf(info_buf, sizeof(info_buf), "%s-%s-%ld-%s-%s",
758            name.nodename, 
759            ( cuserid(userid)[0] == 0 ) ? "???" : userid,
760            /* getenv("USER"), */
761            (long)getpid(), x, request
762           );
763 #endif
764
765    return info_buf;
766 }
767
768 void lsb_putbits(unsigned& target, unsigned position_from_lsb, 
769              unsigned bits, unsigned source)
770 {
771    target |= ((source & ~( ~0 << bits )) << position_from_lsb) ;
772 }
773
774 unsigned lsb_getbits(unsigned source, unsigned position_from_lsb, unsigned bits)
775 {
776    return ( ( source >> position_from_lsb ) & ~( ~0 << bits ) );
777 }
778
779 Boolean cc_is_digit(istream& in)
780 {
781   int c = in.get();
782   int ok = isdigit(c);
783   in.putback(c);
784
785   return ( ok ) ? true : false;
786 }
787
788 unsigned long disk_space(const char* path)
789 {
790 #if defined(__osf__) || defined (hpux) || defined (SVR4) || defined(CSRG_BASED)
791    struct statvfs statfs_buf;
792 #else
793    struct statfs statfs_buf;
794 #endif
795
796    long free_bytes;
797
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 ;
801 #else
802    if ( statfs(path, &statfs_buf) == 0 ) {
803       free_bytes = statfs_buf.f_bavail * statfs_buf.f_bsize ;
804 #endif
805
806    } else {
807       throw(stringException(form("statfs failed on %s", path)));
808    }
809
810    return free_bytes;
811 }
812
813 Boolean writeToTmpFile(char* unique_nm, char* str, int size)
814 {
815     Boolean ok = false;
816     fstream *out = 0;
817     char* tmp_dir_tbl[4];
818     int len;
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");
823
824     int tmp_dir_tbl_size = 4;
825
826     const char* uid = unique_id();
827
828     for ( int i=0; i<tmp_dir_tbl_size; i++ ) {
829
830        if ( tmp_dir_tbl[i] == 0 )
831           continue;
832
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),
836                          len) + len) = '\0';
837
838        mtry {
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 )
842             continue;
843
844           out = new fstream(unique_nm, ios::out);
845
846           if ( !(*out) ) {
847              delete out;
848              continue;
849           }
850    
851           if ( ! (out->write(str, size) ) ) {
852              out -> close();
853              delete out;
854              del_file(unique_nm);
855              continue;
856           } else {
857              ok = true;
858              out -> close();
859              delete out;
860              break;
861           }
862    
863        }
864        mcatch_any()
865        {
866          continue;
867        }
868        end_try;
869
870     }
871    return ok;
872 }