source: CMT/v1r16p20040901/src/cmt_system.cxx @ 1

Last change on this file since 1 was 1, checked in by arnault, 19 years ago

Import all tags

File size: 45.5 KB
Line 
1//-----------------------------------------------------------
2// Copyright Christian Arnault LAL-Orsay CNRS
3// arnault@lal.in2p3.fr
4// See the complete license in cmt_license.txt "http://www.cecill.info".
5//-----------------------------------------------------------
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <errno.h>
11
12#ifdef WIN32
13#include <direct.h>
14#define chdir _chdir
15#define rmdir _rmdir
16//#define mkdir _mkdir
17#define getcwd _getcwd
18#define popen _popen
19#define pclose _pclose
20#define S_IFDIR _S_IFDIR
21#define USE_GETCWD 1
22
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <time.h>
26#include <io.h>
27#include <windows.h>
28
29#define stat _stat
30
31#else
32#include <unistd.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <time.h>
36#include <dirent.h>
37#endif
38
39#ifdef __hpux__
40#define USE_GETCWD 1
41#endif
42
43#ifdef __linux__
44#define USE_GETCWD 1
45#endif
46
47#ifdef USE_GETCWD
48char* getwd (const char* name)
49{
50  char dir[256];
51  getcwd (dir, sizeof (dir));
52  strcpy ((char*) name, dir);
53  return ((char*) name);
54}
55#endif
56
57#include "cmt_system.h"
58#include "cmt_error.h"
59
60//--------------------------------------------------
61cmt_string CmtSystem::pwd ()
62{
63  char buffer[256] = "";
64  char* ptr = 0;
65  char* pwd_env = 0;
66
67#ifdef USE_PWD
68  pwd_env = ::getenv ("PWD"); 
69#endif
70
71  if (pwd_env != 0)
72    {
73      strcpy (buffer, pwd_env);
74    }
75  else
76    {
77      ptr = getcwd (buffer, sizeof (buffer));
78    }
79
80  const char* t = &buffer[0];
81  return ((cmt_string) t);
82}
83
84//--------------------------------------------------
85bool CmtSystem::cd (const cmt_string& dir)
86{
87  static cmt_string new_dir;
88
89  if ((dir.size () == 2) && (dir[1] == ':'))
90    {
91      new_dir = dir;
92      new_dir += file_separator ();
93      if (chdir (new_dir.c_str ()) == 0) 
94        {
95#ifdef USE_PWD
96          new_dir = "PWD=";
97          new_dir += dir;
98          new_dir += file_separator ();
99          putenv (new_dir);
100#endif
101
102          return (true);
103        }
104      return (false);
105    }
106  else
107    {
108      if (chdir (dir.c_str ()) == 0) 
109        {
110#ifdef USE_PWD
111          new_dir = "PWD=";
112          new_dir += dir;
113          putenv (new_dir);
114#endif
115
116          return (true);
117        }
118      return (false);
119    }
120}
121
122//--------------------------------------------------
123void CmtSystem::basename (const cmt_string& file_name, cmt_string& result)
124{
125  int pos = file_name.find_last_of ('/');
126  if (pos == cmt_string::npos)
127    {
128      pos = file_name.find_last_of ('\\');
129    }
130
131  if (pos == cmt_string::npos)
132    {
133      result = file_name;
134    }
135  else
136    {
137      file_name.substr (pos + 1, result);
138    }
139}
140
141//--------------------------------------------------
142void CmtSystem::basename (const cmt_string& file_name,
143                          const cmt_string& /*suffix*/,
144                          cmt_string& result)
145{
146  basename (file_name, result);
147
148  int pos;
149
150  pos = result.find_last_of ('.');
151
152  if (pos != cmt_string::npos)
153    {
154      result.erase (pos);
155    }
156}
157
158//--------------------------------------------------
159void CmtSystem::dirname (const cmt_string& file_name, cmt_string& result)
160{
161  int pos = file_name.find_last_of ('/');
162  if (pos == cmt_string::npos)
163    {
164      pos = file_name.find_last_of ('\\');
165    }
166
167  if (pos == cmt_string::npos)
168    {
169      result = "";
170    }
171  else
172    {
173      result = file_name;
174      result.erase (pos);
175    }
176}
177
178//--------------------------------------------------
179void CmtSystem::name (const cmt_string& file_name, cmt_string& result)
180{
181  int pos;
182
183  result = file_name;
184
185  // remove the suffix
186
187  pos = result.find_last_of ('.');
188
189  if (pos != cmt_string::npos)
190    {
191      result.erase (pos);
192    }
193
194  // remove the directory name
195
196  pos = result.find_last_of ('/');
197  if (pos == cmt_string::npos)
198    {
199      pos = result.find_last_of ('\\');
200    }
201
202  if (pos != cmt_string::npos)
203    {
204      result.erase (0, pos + 1);
205    }
206}
207
208//-------------------------------------------------
209void CmtSystem::get_suffix (const cmt_string& file, cmt_string& result)
210{
211  int pos = file.find_last_of ('.');
212  int sep = file.find_last_of (file_separator ());
213
214  if ((pos == cmt_string::npos) || (pos < sep))
215    {
216      result = "";
217    }
218  else
219    {
220      file.substr (pos + 1, result);
221    }
222}
223
224//-------------------------------------------------
225void CmtSystem::get_dot_suffix (const cmt_string& file, cmt_string& result)
226{
227  int pos = file.find_last_of ('.');
228  int sep = file.find_last_of (file_separator ());
229
230  if ((pos == cmt_string::npos) || (pos < sep))
231    {
232      result = "";
233    }
234  else
235    {
236      file.substr (pos, result);
237    }
238}
239
240//--------------------------------------------------
241bool CmtSystem::has_prefix (const cmt_string& name)
242{
243  if ((name.find ('/') == cmt_string::npos) &&
244      (name.find ('\\') == cmt_string::npos))
245    {
246      return (false);
247    }
248
249  return (true);
250}
251
252//--------------------------------------------------
253bool CmtSystem::absolute_path (const cmt_string& name)
254{
255  if (name.size () == 0) return (false);
256
257  if ((name[0] == '/') ||
258      (name[0] == '\\')) return (true);
259
260  if (name.size () >= 2)
261    {
262      if (name[1] == ':')
263        {
264          return (true);
265        }
266    }
267  return (false);
268}
269
270//--------------------------------------------------
271bool CmtSystem::has_device (const cmt_string& name)
272{
273#ifdef WIN32
274  if (name.size () == 0) return (false);
275
276  if (name.size () >= 2)
277    {
278      if (name[1] == ':')
279        {
280          return (true);
281        }
282      else if ((name[0] == '\\') && (name[1] == '\\'))
283        {
284          return (true);
285        }
286    }
287#endif
288
289  return (false);
290}
291
292//--------------------------------------------------
293cmt_string CmtSystem::current_branch ()
294{
295  cmt_string result;
296
297  basename (pwd (), result);
298
299  return (result);
300}
301
302//--------------------------------------------------
303bool CmtSystem::test_directory (const cmt_string& name)
304{
305  struct stat file_stat;
306  int status;
307
308  status = stat (name.c_str (), &file_stat);
309
310  if (status == 0)
311    {
312      if ((file_stat.st_mode & S_IFDIR) == 0)
313        {
314          return (false);
315        }
316      else
317        {
318          return (true);
319        }
320    }
321  else
322    {
323      return (false);
324    }
325}
326
327//--------------------------------------------------
328bool CmtSystem::test_file (const cmt_string& name)
329{
330  struct stat file_stat;
331  int status;
332
333  status = stat (name.c_str (), &file_stat);
334
335  if (status == 0)
336    {
337      if ((file_stat.st_mode & S_IFDIR) == 0)
338        {
339          return (true);
340        }
341      else
342        {
343          return (false);
344        }
345    }
346  else
347    {
348      return (false);
349    }
350}
351
352//--------------------------------------------------
353bool CmtSystem::compare_files (const cmt_string& name1,
354                               const cmt_string& name2)
355{
356  struct stat file_stat1;
357  struct stat file_stat2;
358  int status;
359
360  status = stat (name1.c_str (), &file_stat1);
361
362  if (status == 0)
363    {
364      if ((file_stat1.st_mode & S_IFDIR) != 0)
365        {
366          return (false);
367        }
368    }
369  else
370    {
371      return (false);
372    }
373
374  status = stat (name2.c_str (), &file_stat2);
375
376  if (status == 0)
377    {
378      if ((file_stat2.st_mode & S_IFDIR) != 0)
379        {
380          return (false);
381        }
382    }
383  else
384    {
385      return (false);
386    }
387
388  if (((int) file_stat1.st_size) != ((int) file_stat2.st_size))
389    {
390      return (false);
391    }
392
393  static cmt_string s1;
394  static cmt_string s2;
395
396  s1.read (name1);
397  s2.read (name2);
398
399  return ((s1 == s2));
400}
401
402//--------------------------------------------------
403//
404// Check if the file "name1" is identical to "name2"
405// if they are identical, "name1" will be simply deleted
406// otherwise "name1" will be copied to "name2" and deleted afterwards
407//
408//--------------------------------------------------
409bool CmtSystem::compare_and_update_files (const cmt_string& name1,
410                                          const cmt_string& name2)
411{
412  struct stat file_stat1;
413  struct stat file_stat2;
414  static cmt_string s1;
415  static cmt_string s2;
416  int status;
417
418  status = stat (name1.c_str (), &file_stat1);
419
420  if (status == 0)
421    {
422      if ((file_stat1.st_mode & S_IFDIR) != 0)
423        {
424          // name1 is a directory.
425          return (false);
426        }
427    }
428  else
429    {
430      // name1 does not exist
431      return (false);
432    }
433
434  s1.read (name1);
435
436  status = stat (name2.c_str (), &file_stat2);
437
438  if (status == 0)
439    {
440      if ((file_stat2.st_mode & S_IFDIR) != 0)
441        {
442          // name2 is a directory
443          return (false);
444        }
445
446      if (((int) file_stat1.st_size) == ((int) file_stat2.st_size))
447        {
448          s2.read (name2);
449          if (s1 == s2)
450            {
451              unlink (name1);
452              return (true);
453            }
454        }
455    }
456
457  FILE* f = fopen (name2, "wb");
458  if (f != NULL)
459    {
460      s1.write (f);
461      fclose (f);
462
463      unlink (name1);
464
465      return (true);
466    }
467  else
468    {
469      //
470      // keep the new file "name1" since it cannot be
471      // copied to "name2"
472      //
473      return (false);
474    }
475}
476
477//--------------------------------------------------
478int CmtSystem::file_size (const cmt_string& name)
479{
480  struct stat file_stat;
481  int status;
482
483  status = stat (name.c_str (), &file_stat);
484
485  if (status == 0)
486    {
487      return ((int) file_stat.st_size);
488    }
489  else
490    {
491      return (0);
492    }
493}
494
495//--------------------------------------------------
496char CmtSystem::file_separator ()
497{
498#ifdef WIN32
499  return ('\\');
500#else
501  return ('/');
502#endif
503}
504
505/**
506 *  Transform all / or \ characters in the text into the current file_separator
507 *  Reduce all multiple file_separator into single ones.
508 */
509void CmtSystem::reduce_file_separators (cmt_string& text)
510{
511  if (file_separator () == '/')
512    {
513      text.replace_all ("\\", "/");
514      while (text.find ("//") != cmt_string::npos)
515        {
516          text.replace_all ("//", "/");
517        }
518    }
519  else
520    {
521      text.replace_all ("/", "\\");
522      while (text.find ("\\\\") != cmt_string::npos)
523        {
524          text.replace_all ("\\\\", "\\");
525        }
526    }
527}
528
529//--------------------------------------------------
530char CmtSystem::path_separator ()
531{
532#ifdef WIN32
533  return (';');
534#else
535  return (':');
536#endif
537}
538
539//--------------------------------------------------
540char CmtSystem::command_separator ()
541{
542#ifdef WIN32
543  return ('&');
544#else
545  return (';');
546#endif
547}
548
549//--------------------------------------------------
550const cmt_string& CmtSystem::ev_open ()
551{
552#ifdef WIN32
553  static const cmt_string s = "%";
554#else
555  static const cmt_string s = "${";
556#endif
557
558  return (s);
559}
560
561//--------------------------------------------------
562const cmt_string& CmtSystem::ev_close ()
563{
564#ifdef WIN32
565  static const cmt_string s = "%";
566#else
567  static const cmt_string s = "}";
568#endif
569
570  return (s);
571}
572
573//-------------------------------------------------
574bool CmtSystem::create_symlink (const cmt_string& oldname,
575                                const cmt_string& newname)
576{
577  ::unlink (newname.c_str ());
578
579#ifdef WIN32
580  int status = 1;
581#else
582  int status = ::symlink (oldname.c_str (), newname.c_str ());
583#endif
584
585  if (status == 0) return (true);
586  return (false);
587}
588
589//-------------------------------------------------
590bool CmtSystem::remove_file (const cmt_string& name)
591{
592  if (::unlink (name) != 0)
593    {
594      cerr << "#CMT> Cannot remove file " << name << endl;
595      return (false);
596    }
597
598  return (true);
599}
600
601//-------------------------------------------------
602bool CmtSystem::remove_directory (const cmt_string& name)
603{
604  //cout << "Try to remove directory " << name << endl;
605
606  cmt_string_vector files;
607
608  scan_dir (name, files);
609
610  for (int i = 0; i < files.size (); i++)
611    {
612      cmt_string& file = files[i];
613
614      if (test_directory (file))
615        {
616          if (!remove_directory (file)) return (false);
617        }
618      else
619        {
620          if (!remove_file (file)) return (false);
621        }
622    }
623 
624  int status = ::rmdir (name);
625  if (status != 0)
626    {
627      cerr << "#CMT> Cannot remove directory " << name << " errno=" << errno << endl;
628      return (false);
629    }
630
631  return (true);
632}
633
634//-------------------------------------------------
635bool CmtSystem::mkdir (const cmt_string& name)
636{
637  static cmt_string_vector path_vector;
638  int i;
639  static cmt_string full_path;
640  char double_fs[] = "  ";
641
642  double_fs[0] = file_separator ();
643  double_fs[1] = file_separator ();
644
645  full_path = name;
646
647  if (file_separator () == '/')
648    {
649      full_path.replace_all ("\\", file_separator ());
650    }
651  else
652    {
653      full_path.replace_all ("/", file_separator ());
654    }
655
656  full_path.replace_all (double_fs, file_separator ());
657
658  split (full_path, file_separator (), path_vector);
659
660  full_path = "";
661
662  if (absolute_path (name))
663    {
664      if (!has_device (name))
665        {
666          full_path = file_separator ();
667        }
668    }
669
670  for (i = 0; i < path_vector.size (); i++)
671    {
672      const cmt_string& path = path_vector[i];
673
674      if (i > 0) full_path += file_separator ();
675      full_path += path;
676
677      if (has_device (path)) continue;
678
679      if (!test_directory (full_path))
680        {
681#ifdef WIN32
682          if (::_mkdir (full_path.c_str ()) != 0)
683            {
684                // cerr << "CMT> cannot create directory " << full_path << endl;
685              return (false);
686            }
687#else
688          if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
689            {
690                // cerr << "CMT> cannot create directory " << full_path << endl;
691              return (false);
692            }
693#endif
694        }
695    }
696
697  return (true);
698}
699
700//----------------------------------------------------------
701void CmtSystem::scan_dir (const cmt_string& dir_name,
702                          cmt_string_vector& list)
703{
704  static cmt_string dir_prefix;
705  static cmt_string name_prefix;
706
707  dir_prefix = dir_name;
708  if (dir_name == "") dir_prefix = ".";
709
710  if (!test_directory (dir_prefix))
711    {
712      dirname (dir_prefix, dir_prefix);
713      basename (dir_name, name_prefix);
714    }
715  else
716    {
717    }
718
719  bool need_filter = false;
720
721  int wild_card;
722
723  wild_card = name_prefix.find ('*');
724  if (wild_card != cmt_string::npos)
725    {
726      name_prefix.erase (wild_card);
727    }
728
729  if (name_prefix.size () > 0)
730    {
731      need_filter = true;
732    }
733
734  list.clear ();
735
736#ifdef WIN32
737
738  long dir;
739  struct _finddata_t entry;
740
741  static cmt_string search;
742
743  search = dir_prefix;
744  search += file_separator ();
745  search += "*";
746
747  dir = _findfirst (search.c_str (), &entry);
748  if (dir > 0)
749    {
750      for (;;)
751        {
752          if ((strcmp ((char*) entry.name, ".") != 0) &&
753              (strcmp ((char*) entry.name, "..") != 0) &&
754              (strncmp ((char*) entry.name, ".nfs", 4) != 0))
755            {
756              const char* name = entry.name;
757
758              if (!need_filter ||
759                  (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
760                {
761                  cmt_string& name_entry = list.add ();
762
763                  name_entry = dir_prefix;
764                  name_entry += file_separator ();
765                  name_entry += name;
766                }
767            }
768
769          int status = _findnext (dir, &entry);
770          if (status != 0)
771            {
772              break;
773            }
774        }
775
776      _findclose (dir);
777    }
778#else
779
780  //cout << "scan_dir> dir=" << dir_name << endl;
781
782  DIR* dir = opendir (dir_prefix.c_str ());
783
784  struct dirent* entry;
785
786  if (dir != 0)
787    {
788      while ((entry = readdir (dir)) != 0)
789        {
790          //if (entry->d_name[0] == '.') continue;
791          if (!strcmp ((char*) entry->d_name, ".")) continue;
792          if (!strcmp ((char*) entry->d_name, "..")) continue;
793          if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
794
795          const char* name = entry->d_name;
796
797          if (need_filter &&
798              (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
799
800          //cout << "scan_dir> name=" << name << endl;
801
802          cmt_string& name_entry = list.add ();
803
804          name_entry = dir_prefix;
805          name_entry += file_separator ();
806          name_entry += name;
807        }
808
809      closedir (dir);
810    }
811#endif
812
813}
814
815//----------------------------------------------------------
816void CmtSystem::scan_dir (const cmt_string& dir_name,
817                          const cmt_regexp& expression,
818                          cmt_string_vector& list)
819{
820  static cmt_string dir_prefix;
821
822  dir_prefix = dir_name;
823  if (dir_name == "") dir_prefix = ".";
824
825  if (!test_directory (dir_prefix))
826    {
827      dirname (dir_prefix, dir_prefix);
828    }
829
830  list.clear ();
831
832#ifdef WIN32
833
834  long dir;
835  struct _finddata_t entry;
836
837  static cmt_string search;
838
839  search = dir_prefix;
840  search += file_separator ();
841  search += "*";
842
843  dir = _findfirst (search.c_str (), &entry);
844  if (dir > 0)
845    {
846      for (;;)
847        {
848          if ((entry.name[0] != '.') &&
849              (strcmp ((char*) entry.name, ".") != 0) &&
850              (strcmp ((char*) entry.name, "..") != 0) &&
851              (strncmp ((char*) entry.name, ".nfs", 4) != 0))
852            {
853              const char* name = entry.name;
854             
855              if (expression.match (name))
856                {
857                  cmt_string& name_entry = list.add ();
858
859                  name_entry = dir_prefix;
860                  name_entry += file_separator ();
861                  name_entry += name;
862                }
863            }
864
865          int status = _findnext (dir, &entry);
866          if (status != 0)
867            {
868              break;
869            }
870        }
871      _findclose (dir);
872    }
873#else
874
875  //cout << "scan_dir> dir=" << dir_name << endl;
876
877  DIR* dir = opendir (dir_prefix.c_str ());
878
879  struct dirent* entry;
880
881  if (dir != 0)
882    {
883      while ((entry = readdir (dir)) != 0)
884        {
885          //if (entry->d_name[0] == '.') continue;
886          if (!strcmp ((char*) entry->d_name, ".")) continue;
887          if (!strcmp ((char*) entry->d_name, "..")) continue;
888          if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
889
890          const char* name = entry->d_name;
891
892          if (!expression.match (name)) continue;
893
894          cmt_string& name_entry = list.add ();
895
896          name_entry = dir_prefix;
897          name_entry += file_separator ();
898          name_entry += name;
899        }
900
901      closedir (dir);
902    }
903#endif
904
905}
906
907//----------------------------------------------------------
908CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
909{
910  static cmt_string_vector result;
911
912  scan_dir (dir_name, result);
913
914  return (result);
915}
916
917//----------------------------------------------------------
918const cmt_string& CmtSystem::get_cmt_root ()
919{
920  static cmt_string root;
921
922  root = "";
923
924  const char* env = ::getenv ("CMTROOT");
925  if (env != 0)
926    {
927      root = env;
928
929      dirname (root, root);
930      dirname (root, root);
931      return (root);
932    }
933
934#ifdef WIN32
935  LONG status;
936  HKEY key = 0;
937
938  status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
939                         0, KEY_READ, &key);
940  if (status == ERROR_SUCCESS)
941    {
942      char temp[256];
943      DWORD length = sizeof (temp) - 1;
944      DWORD type;
945
946      status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
947      if (status == ERROR_SUCCESS)
948        {
949          root = temp;
950          return (root);
951        }
952    }
953#endif
954
955  return (root);
956}
957
958//----------------------------------------------------------
959void CmtSystem::get_cmt_version (cmt_string& version)
960{
961  version = "";
962
963  const char* env = ::getenv ("CMTROOT");
964  if (env != 0)
965    {
966      cmt_string s = env;
967      basename (s, version);
968    }
969  else
970    {
971#ifdef WIN32
972      LONG status;
973      HKEY key = 0;
974
975      status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
976                             0, KEY_READ, &key);
977      if (status == ERROR_SUCCESS)
978        {
979          char temp[256];
980          DWORD length = sizeof (temp) - 1;
981          DWORD type;
982         
983          status = RegQueryValueEx (key, "version", 0, &type, 
984                                    (LPBYTE) temp, &length);
985          if (status == ERROR_SUCCESS)
986            {
987              version = temp;
988            }
989        }
990#endif
991    }
992}
993
994//----------------------------------------------------------
995cmt_string CmtSystem::get_cmt_config ()
996{
997  const char* env = ::getenv ("CMTCONFIG");
998  if (env != 0)
999    {
1000      return (cmt_string (env));
1001    }
1002
1003  env = ::getenv ("CMTBIN");
1004  if (env != 0)
1005    {
1006      return (cmt_string (env));
1007    }
1008
1009#ifdef WIN32
1010  LONG status;
1011  HKEY key = 0;
1012
1013  status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
1014                         0, KEY_READ, &key);
1015  if (status == ERROR_SUCCESS)
1016    {
1017      char temp[256];
1018      DWORD length = sizeof (temp) - 1;
1019      DWORD type;
1020
1021      status = RegQueryValueEx (key, "config", 0, &type, 
1022                                (LPBYTE) temp, &length);
1023      if (status == ERROR_SUCCESS)
1024        {
1025          cmt_string config (temp);
1026          return (config);
1027        }
1028    }
1029
1030  return ("VisualC");
1031#endif
1032
1033  return ("");
1034
1035}
1036
1037//----------------------------------------------------------
1038cmt_string CmtSystem::get_cmt_site ()
1039{
1040  const char* env = ::getenv ("CMTSITE");
1041  if (env != 0)
1042    {
1043      return (cmt_string (env));
1044    }
1045
1046#ifdef WIN32
1047  LONG status;
1048  HKEY key = 0;
1049
1050  status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
1051                         0, KEY_READ, &key);
1052  if (status == ERROR_SUCCESS)
1053    {
1054      char temp[256];
1055      DWORD length = sizeof (temp) - 1;
1056      DWORD type;
1057
1058      status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
1059      if (status == ERROR_SUCCESS)
1060        {
1061          cmt_string site (temp);
1062          return (site);
1063        }
1064    }
1065#endif
1066
1067  return ("");
1068}
1069
1070//----------------------------------------------------------
1071void CmtSystem::get_uname (cmt_string& uname)
1072{
1073#ifdef WIN32
1074  uname = "WIN32";
1075#else
1076
1077  uname = "";
1078
1079  FILE* file;
1080
1081  file = popen ("uname", "r");
1082
1083  if (file != 0)
1084    {
1085      char line[1024];
1086      char* ptr;
1087      char* nl;
1088
1089      line[0] = 0;
1090      ptr = fgets (line, sizeof (line), file);
1091      if (ptr != 0)
1092        {
1093          nl = strrchr (ptr, '\n');
1094          if (nl != 0) *nl = 0;
1095
1096          uname = ptr;
1097        }
1098      pclose (file);
1099    }
1100#endif
1101}
1102
1103//----------------------------------------------------------
1104void CmtSystem::get_hosttype (cmt_string& hosttype)
1105{
1106  hosttype = "";
1107
1108  char* ptr;
1109
1110  ptr = ::getenv ("HOSTTYPE");
1111  if (ptr != 0)
1112    {
1113      hosttype = ptr;
1114    }
1115}
1116
1117//----------------------------------------------------------
1118cmt_string CmtSystem::get_temporary_name ()
1119{
1120  cmt_string name;
1121
1122  name = ::tmpnam (NULL);
1123
1124  return (name);
1125}
1126
1127//----------------------------------------------------------
1128cmt_string CmtSystem::get_home_package ()
1129{
1130  cmt_string name = "CMTHOME";
1131
1132  return (name);
1133}
1134
1135//----------------------------------------------------------
1136bool CmtSystem::is_home_package (const cmt_string& name,
1137                                 const cmt_string& version)
1138{
1139  if (name == "CMTHOME") return (true);
1140
1141  return (false);
1142}
1143
1144//----------------------------------------------------------
1145cmt_string CmtSystem::get_user_context_package ()
1146{
1147  cmt_string name = "CMTUSERCONTEXT";
1148
1149  return (name);
1150}
1151
1152//----------------------------------------------------------
1153bool CmtSystem::is_user_context_package (const cmt_string& name,
1154                                         const cmt_string& version)
1155{
1156  if (name == "CMTUSERCONTEXT") return (true);
1157
1158  return (false);
1159}
1160
1161//----------------------------------------------------------
1162cmt_string CmtSystem::get_project_package ()
1163{
1164  cmt_string name = "PROJECT";
1165
1166  return (name);
1167}
1168
1169//----------------------------------------------------------
1170bool CmtSystem::is_project_package (const cmt_string& name,
1171                                    const cmt_string& version)
1172{
1173  if (name == "PROJECT") return (true);
1174
1175  return (false);
1176}
1177
1178//----------------------------------------------------------
1179bool CmtSystem::testenv (const cmt_string& name)
1180{
1181  const char* env = ::getenv (name);
1182  if (env == 0) return (false);
1183  return (true);
1184}
1185
1186//----------------------------------------------------------
1187cmt_string CmtSystem::getenv (const cmt_string& name)
1188{
1189  cmt_string result;
1190
1191  const char* env = ::getenv (name);
1192  if (env != 0)
1193    {
1194      result = env;
1195    }
1196
1197  if (name == "CMTCONFIG")
1198  {
1199    return (get_cmt_config ());
1200  }
1201
1202  /*
1203  if (name == "CMTROOT")
1204  {
1205          return (get_cmt_root ());
1206  }
1207
1208  if (name == "CMTSITE")
1209  {
1210          return (get_cmt_site ());
1211  }
1212  */
1213
1214  return (result);
1215}
1216
1217//----------------------------------------------------------
1218bool CmtSystem::putenv (const cmt_string& name_value)
1219{
1220  int status = ::putenv ((char*) name_value.c_str ());
1221
1222  if (status == 0) return (true);
1223  else return (false);
1224}
1225
1226//----------------------------------------------------------
1227void CmtSystem::add_cmt_path (const cmt_string& path,
1228                              const cmt_string& path_source,
1229                              IProjectFactory& factory)
1230{
1231  cmt_string npath = path;
1232
1233  if (npath == "") return;
1234
1235#ifdef WIN32
1236  if (npath.size () == 2)
1237    {
1238      if (npath[1] == ':')
1239        {
1240          npath += file_separator ();
1241        }
1242    }
1243#endif
1244
1245  npath.replace_all ("\\", file_separator ());
1246  npath.replace_all ("/", file_separator ());
1247
1248  if (!test_directory (npath))
1249    {
1250      CmtError::set (CmtError::path_not_found, npath);
1251      return;
1252    }
1253
1254  factory.create_project (path, path_source);
1255}
1256
1257//----------------------------------------------------------
1258static void add_cmt_paths_from_text (const cmt_string& text,
1259                                     const cmt_string& context,
1260                                     IProjectFactory& factory)
1261{
1262  static CmtSystem::cmt_string_vector path_vector;
1263  int i;
1264
1265  CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
1266
1267  for (i = 0; i < path_vector.size (); i++)
1268    {
1269      const cmt_string& path = path_vector[i];
1270
1271      CmtSystem::add_cmt_path (path, context, factory);
1272    }
1273}
1274
1275//----------------------------------------------------------
1276static void add_cmt_paths (const cmt_string& file_name, IProjectFactory& factory)
1277{
1278  if (!CmtSystem::test_file (file_name)) return;
1279
1280  static cmt_string text;
1281
1282  text.read (file_name);
1283
1284  int pos = text.find ("CMTPATH");
1285  if (pos == cmt_string::npos) return;
1286  pos += strlen ("CMTPATH");
1287  pos = text.find (pos, "=");
1288  if (pos == cmt_string::npos) return;
1289  pos++;
1290
1291  text.erase (0, pos);
1292
1293  int nl = text.find (pos, "\n");
1294  if (nl != cmt_string::npos) text.erase (nl);
1295
1296  add_cmt_paths_from_text (text, file_name, factory);
1297}
1298
1299//----------------------------------------------------------
1300void CmtSystem::get_cmt_paths (IProjectFactory& factory, const cmt_string& init_text)
1301{
1302  if (init_text != "")
1303    {
1304      add_cmt_paths_from_text (init_text, "initialization", factory);
1305    }
1306
1307#ifdef WIN32
1308  LONG status;
1309  HKEY key = 0;
1310
1311  status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
1312                         0, KEY_READ, &key);
1313  if (status == ERROR_SUCCESS)
1314    {
1315      DWORD index = 0;
1316      char name[256];
1317      char temp[256];
1318
1319      for (;;)
1320        {
1321          DWORD name_length = sizeof (name) - 1;
1322          DWORD length = sizeof (temp) - 1;
1323          DWORD type;
1324          status = RegEnumValue (key, index,
1325                                 name, &name_length, 0, &type,
1326                                 (LPBYTE) temp, &length);
1327          if ((status == ERROR_SUCCESS) ||
1328              (status == 234))
1329            {
1330              const cmt_string path = temp;
1331              add_cmt_path (path, "HKEY_CURRENT_USER", factory);
1332            }
1333
1334          if (status == 259)
1335            {
1336              break;
1337            }
1338
1339          index++;
1340        }
1341    }
1342
1343  status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
1344                         0, KEY_READ, &key);
1345  if (status == ERROR_SUCCESS)
1346    {
1347      DWORD index = 0;
1348      char name[256];
1349      char temp[256];
1350
1351      for (;;)
1352        {
1353          DWORD type;
1354          DWORD name_length = sizeof (name) - 1;
1355          DWORD length = sizeof (temp) - 1;
1356
1357
1358          status = RegEnumValue (key, index,
1359                                 name, &name_length, 0, &type,
1360                                 (LPBYTE) temp, &length);
1361          if (status != ERROR_NO_MORE_ITEMS)
1362            {
1363              const cmt_string path = temp;
1364              add_cmt_path (path, "HKEY_LOCAL_MACHINE", factory);
1365            }
1366          else
1367            {
1368              break;
1369            }
1370          index++;
1371        }
1372    }
1373
1374#endif
1375
1376  //-----------------------------------------
1377  // look for .cmtrc files :
1378  //  first look in ./
1379  //  then in "~/"
1380  //  then in ${CMTROOT}/mgr
1381  //-----------------------------------------
1382  cmt_string rc_name;
1383
1384  const cmt_string env = CmtSystem::getenv ("CMTPATH");
1385
1386  if (env != "")
1387    {
1388      static cmt_string_vector path_vector;
1389      int i;
1390
1391      split (env, path_separator (), path_vector);
1392
1393      for (i = 0; i < path_vector.size (); i++)
1394        {
1395          const cmt_string& path = path_vector[i];
1396
1397          add_cmt_path (path, "${CMTPATH}", factory);
1398        }
1399    }
1400
1401  add_cmt_paths (".cmtrc", factory);
1402
1403  if (get_home_directory (rc_name))
1404    {
1405      rc_name += file_separator ();
1406      rc_name += ".cmtrc";
1407      add_cmt_paths (rc_name, factory);
1408    }
1409
1410  rc_name = get_cmt_root ();
1411  rc_name += file_separator ();
1412  rc_name += "CMT";
1413  rc_name += file_separator ();
1414  cmt_string version;
1415  get_cmt_version (version);
1416  rc_name += version;
1417  rc_name += file_separator ();
1418  rc_name += "mgr";
1419  rc_name += file_separator ();
1420  rc_name += ".cmtrc";
1421
1422  add_cmt_paths (rc_name, factory);
1423
1424  add_cmt_path (get_cmt_root (), "default path", factory);
1425}
1426
1427//----------------------------------------------------------
1428int CmtSystem::execute (const cmt_string& command)
1429{
1430  //cout << "CmtSystem::execute1> [" << command << "]" << endl;
1431
1432  return (system (command.c_str ()));
1433}
1434
1435//----------------------------------------------------------
1436int CmtSystem::execute (const cmt_string& command, cmt_string& output)
1437{
1438  output = "";
1439
1440  //cout << "CmtSystem::execute2> [" << command << "]" << endl;
1441
1442  FILE* f = popen (command.c_str (), "r"); 
1443 
1444  if (f != 0) 
1445    { 
1446      char line[256]; 
1447      char* ptr;
1448
1449      while ((ptr = fgets (line, sizeof (line), f)) != NULL) 
1450        {
1451          output += ptr;
1452        } 
1453      pclose (f);
1454
1455      return (0);
1456    }
1457
1458  return (1);
1459}
1460
1461//----------------------------------------------------------
1462bool CmtSystem::is_package_directory (const cmt_string& name)
1463{
1464  cmt_string_vector dirs;
1465
1466  cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
1467
1468  scan_dir (name, exp, dirs);
1469
1470  cmt_string req;
1471
1472  req = name;
1473  req += file_separator ();
1474  req += "cmt";
1475  req += file_separator ();
1476  req += "requirements";
1477
1478  if (test_file (req)) return (true);
1479
1480  if (dirs.size () == 0) 
1481    {
1482      return (false);
1483    }
1484
1485  for (int i = 0; i < dirs.size (); i++)
1486      {
1487        const cmt_string& d = dirs[i];
1488
1489        req = d;
1490        req += file_separator ();
1491        req += "mgr";
1492        req += file_separator ();
1493        req += "requirements";
1494
1495        if (test_file (req)) return (true);
1496
1497      req = d;
1498      req += file_separator ();
1499      req += "cmt";
1500      req += file_separator ();
1501      req += "requirements";
1502     
1503      if (test_file (req)) return (true);
1504    }
1505
1506  return (false);
1507}
1508
1509//----------------------------------------------------------
1510bool CmtSystem::is_version_directory (const cmt_string& name)
1511{
1512  int v;
1513  int r;
1514  int p;
1515
1516  return (is_version_directory (name, v, r, p));
1517}
1518
1519//----------------------------------------------------------
1520bool CmtSystem::is_version_directory (const cmt_string& name,
1521                                      int& v,
1522                                      int& r,
1523                                      int& p)
1524{
1525  static const cmt_string numbers = "0123456789";
1526
1527  static const int id_version = 0;
1528  static const int id_release = 1;
1529  static const int id_patch   = 2;
1530
1531  cmt_string buffer;
1532
1533  enum 
1534  {
1535    starting,
1536    at_key,
1537    at_number
1538  } state;
1539
1540  int id;
1541  int pos;
1542  int value;
1543
1544  v = 0;
1545  r = 0;
1546  p = 0;
1547
1548  //
1549  // version : v-field
1550  //         | v-field r-field
1551  //         | v-field r-field p-field
1552  //
1553  // v-field : field
1554  // r-field : field
1555  // p-field : field
1556  //
1557  // field   : key '*'
1558  //         | key number
1559  //
1560  // key     : letters
1561  //
1562
1563  state = starting;
1564  id    = id_version;
1565
1566  for (pos = 0; pos < name.size (); pos++)
1567    {
1568      char c = name[pos];
1569
1570      if (c == '*')
1571        {
1572          // A wild card
1573          switch (state)
1574            {
1575            case starting:
1576              // cannot start with a wild card ??
1577              v = -1;
1578              r = -1;
1579              p = -1;
1580              return (false);
1581            case at_key:
1582              // the numeric field is valued with a wild card
1583              switch (id)
1584                {
1585                case id_version:
1586                  v = -1;
1587                case id_release:
1588                  r = -1;
1589                case id_patch:
1590                  p = -1;
1591                  break;
1592                }
1593              return (true);
1594            case at_number:
1595              // question:
1596              // a number followed by a wild-card is considered as:
1597              //   1) a wild card on the number itself (1* comp with 1, 10, 12, 120, etc)
1598              //   2) a wild card on the next fields (1* comp with 1r1, 1-12 etc)
1599              //
1600
1601              //  Here we select option 1)
1602
1603              sscanf (buffer.c_str (), "%d", &value);
1604              switch (id)
1605                {
1606                case id_version:
1607                  //
1608                  // lazy option 1 implies v = -1;
1609                  // strict option 1 would imply v = -value;
1610                  // option 2 implies v = value;
1611                  //
1612
1613                  v = -1;
1614                  r = -1;
1615                  p = -1;
1616                  break;
1617                case id_release:
1618                  r = value;
1619                  p = -1;
1620                  break;
1621                case id_patch:
1622                  p = value;
1623                  break;
1624                }
1625
1626              return (true);
1627            }
1628        }
1629      else if (numbers.find (c) == cmt_string::npos)
1630        {
1631          // A letter
1632          switch (state)
1633            {
1634            case starting:
1635              state = at_key;
1636              break;
1637            case at_key:
1638              // Multiple letter key (is it permitted??)
1639              break;
1640            case at_number:
1641              sscanf (buffer.c_str (), "%d", &value);
1642              switch (id)
1643                {
1644                case id_version:
1645                  v = value;
1646                  break;
1647                case id_release:
1648                  r = value;
1649                  break;
1650                case id_patch:
1651                  p = value;
1652                  break;
1653                }
1654              buffer = "";
1655              id++;
1656              state = at_key;
1657              break;
1658            }
1659        }
1660      else
1661        {
1662          // a number
1663          switch (state)
1664            {
1665            case starting:
1666              // not starting by a letter (syntax error)
1667              return (false);
1668            case at_key:
1669              // the numeric field for the current id is starting now
1670              buffer += c;
1671              state = at_number;
1672              break;
1673            case at_number:
1674              // continuing the current numeric field
1675              buffer += c;
1676              break;
1677            }
1678        }
1679    }
1680
1681  switch (state)
1682    {
1683    case starting:
1684      // Empty version string
1685      return (false);
1686    case at_key:
1687      // Syntax error (when only letters. Ending letters is not an error)
1688      if (id == id_version) return (false);
1689      else return (true);
1690    case at_number:
1691      sscanf (buffer.c_str (), "%d", &value);
1692      switch (id)
1693        {
1694        case id_version:
1695          v = value;
1696          break;
1697        case id_release:
1698          r = value;
1699          break;
1700        case id_patch:
1701          p = value;
1702          break;
1703        }
1704      id++;
1705      state = at_key;
1706      return (true);
1707    }
1708
1709  return (false);
1710}
1711
1712//----------------------------------------------------------
1713//  Split a line into words. Separators are spaces and tabs
1714//  Text enclosed in double quotes is one word.
1715//----------------------------------------------------------
1716void CmtSystem::split (const cmt_string& text,
1717                       const cmt_string& separators,
1718                       cmt_string_vector& strings)
1719{
1720  static char* buffer = 0;
1721  static int allocated = 0;
1722
1723  bool finished = false;
1724
1725  strings.clear ();
1726
1727  if (text.size () == 0) return;
1728
1729  /*
1730    We are going to work in a copy of the text, since
1731    \0 will be inserted right after each found word.
1732
1733    Then the vector of strings is iteratively filled by each found word.
1734  */
1735
1736  if (buffer == 0)
1737    {
1738      allocated = text.size ();
1739      buffer = (char*) malloc (allocated + 1);
1740    }
1741  else
1742    {
1743      if (text.size () > allocated)
1744        {
1745          allocated = text.size ();
1746          buffer = (char*) realloc (buffer, allocated + 1);
1747        }
1748    }
1749
1750  strcpy (buffer, text.c_str ());
1751
1752  /*
1753    Algorithm :
1754
1755    We look for words separated by <separators> which may be
1756    o spaces (' ' or '\t')
1757    o other characters such as ':'
1758
1759    A word is a character string not containing any separator. A substring in
1760    this word my be enclosed between quotes (" or ') which permits separator
1761    inclusion within words.
1762  */
1763
1764  char* current_word = buffer;
1765
1766  while (*current_word != 0)
1767    {
1768      size_t prefix_length;
1769      size_t word_length;
1770
1771      /*
1772        while ((*current_word == ' ') ||
1773        (*current_word == '\t'))
1774        {
1775        current_word++;
1776        }
1777      */
1778
1779      // first skip all starting separators.
1780
1781      prefix_length = strspn (current_word, separators.c_str ());
1782      if (prefix_length > 0)
1783        {
1784          // Move to the first non-separator character
1785
1786          current_word += prefix_length;
1787        }
1788
1789      /*
1790        Parse the next word.
1791
1792        It may contain enclosures in quote characters or not.
1793        Quotes must be identical on both sides of each enclosure.
1794      */
1795
1796      char* running_char = current_word;
1797
1798      word_length = 0;
1799
1800      for (;;)
1801        {
1802          size_t unquoted_length;
1803          size_t separator_offset;
1804
1805          for (int p = 0;;)
1806            {
1807              unquoted_length = strcspn (running_char + p, "\"\'") + p;
1808              if ((unquoted_length > 0) && (running_char[unquoted_length-1] == '\\'))
1809                {
1810                  p = unquoted_length + 1;
1811                }
1812              else
1813                {
1814                  break;
1815                }
1816            }
1817
1818          separator_offset = strcspn (running_char, separators.c_str ());
1819
1820          if (separator_offset <= unquoted_length)
1821            {
1822              // no quote in this word -> we are finished for this one.
1823              running_char += separator_offset;
1824              break;
1825            }
1826
1827          // We have found a quoted enclosure. Move to it.
1828
1829          running_char += unquoted_length;
1830
1831          char quote = running_char[0];
1832
1833          // Remove it.
1834          {
1835            char* p = running_char;
1836            while (p[1] != 0)
1837              {
1838                *p = p[1];
1839                p++;
1840              }
1841            *p = 0;
1842          }
1843
1844          // Look for the next occurence of this quote.
1845          {
1846            char* p = strchr (running_char, quote);
1847            if (p == 0)
1848              {
1849                // Unmatched quote : the rest of the line will be taken as a word...
1850                running_char += strlen (running_char);
1851                finished = true;
1852                break;
1853              }
1854            else
1855              {
1856                running_char = p;
1857              }
1858          }
1859
1860          // Now we remove the ending quote from the word
1861          // (by shifting all remaining characters by one place to the left)
1862
1863          {
1864            char* p = running_char;
1865            while (p[1] != 0)
1866              {
1867                *p = p[1];
1868                p++;
1869              }
1870            *p = 0;
1871          }
1872        }
1873
1874      word_length = running_char - current_word;
1875
1876      if (current_word[word_length] == 0)
1877        {
1878          finished = true;
1879        }
1880      else
1881        {
1882          current_word[word_length] = 0;
1883        }
1884
1885      /*
1886        if ((t[0] == '"') ||
1887        (t[0] == '\'') ||
1888        (t[0] == ':'))
1889        {
1890        char* quote;
1891
1892        t++;
1893        quote = strchr (t, sep);
1894        if (quote != 0) *quote = 0;
1895        else finished = true;
1896        }
1897        else
1898        {
1899        int offset;
1900
1901        offset = strcspn (t, " \t:");
1902        if ((offset < 0) || (t[offset] == 0)) finished = true;
1903        if (!finished)
1904        {
1905        space = t + offset;
1906        *space = 0;
1907        }
1908        }
1909      */
1910
1911      // Store the current word into the vector of strings
1912
1913      {
1914        cmt_string& s = strings.add ();
1915        s = current_word;
1916      }
1917
1918      if (finished) break;
1919
1920      // Move to the next possible word.
1921      current_word += word_length + 1;
1922    }
1923}
1924
1925//----------------------------------------------------------
1926void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
1927{
1928  new_dir = dir;
1929
1930  compress_path (new_dir);
1931}
1932
1933//----------------------------------------------------------
1934//
1935//  We try to detect the aaaa/xxxx/../bbbb patterns which should be
1936// equivalent to aaaa/bbbb
1937//  this therefore consists in removing all /xxxx/../
1938//
1939//----------------------------------------------------------
1940void CmtSystem::compress_path (cmt_string& dir)
1941{
1942#ifdef WIN32
1943  static const char pattern[] = "\\..";
1944    //static const char here[] = ".\\";
1945  static const char fs[] = "\\\\";
1946#else
1947  static const char pattern[] = "/..";
1948    //static const char here[] = "./";
1949  static const char fs[] = "//";
1950#endif
1951
1952  if (dir.size () == 0) return;
1953
1954    //
1955    // We first synchronize to using file_separator() in any case.
1956    //
1957
1958  if (file_separator () == '/')
1959    {
1960      dir.replace_all ("\\", file_separator ());
1961    }
1962  else
1963    {
1964      dir.replace_all ("/", file_separator ());
1965    }
1966
1967  dir.replace_all (fs, file_separator ());
1968
1969  for (;;)
1970    {
1971      int pos1;
1972      int pos2;
1973
1974      pos1 = dir.find (pattern);
1975      if (pos1 == cmt_string::npos) break;
1976
1977        //
1978        // extract "aaaa/xxxx" from "aaaa/xxxx/../bbbb"
1979        //
1980      cmt_string p = dir.substr (0, pos1);
1981     
1982        //
1983        // Is "aaaa/xxxx" only made of "xxxx" ?
1984        //
1985      pos2 = p.find_last_of (file_separator ());
1986     
1987      if (pos2 == cmt_string::npos) 
1988        {
1989          // the pattern was xxxx/..
1990          dir.erase (0, pos1 + 3);
1991        }
1992      else
1993        {
1994          //    01234567890123456
1995          //    aaaa/xxxx/../bbbb
1996          //        2    1   3
1997          //
1998          // erase the "/xxxx/.." pattern
1999          // result will be "aaaa/bbbb"
2000          //
2001          dir.erase (pos2, pos1 + 3 - pos2);
2002        }
2003    }
2004
2005    //if (dir[dir.size () - 1] == file_separator ()) dir.erase (dir.size () - 1);
2006}
2007
2008//----------------------------------------------------------
2009cmt_string CmtSystem::now ()
2010{
2011  cmt_string result;
2012
2013  time_t ltime;
2014  time (&ltime);
2015  result = ctime (&ltime);
2016
2017  result.replace_all ("\n", "");
2018
2019  return (result);
2020}
2021
2022//----------------------------------------------------------
2023cmt_string CmtSystem::user ()
2024{
2025#ifdef _WIN32
2026  cmt_string result = getenv ("USERNAME");
2027#else
2028  cmt_string result = getenv ("USER");
2029#endif
2030
2031  return (result);
2032}
2033
2034//----------------------------------------------------------
2035void CmtSystem::get_cvsroot (cmt_string& cvsroot)
2036{
2037  cvsroot = "";
2038
2039  const char* env = ::getenv ("CVSROOT");
2040  if (env != 0)
2041    {
2042      cvsroot = env;
2043      return;
2044    }
2045
2046#ifdef WIN32
2047  LONG status;
2048  HKEY key = 0;
2049
2050  status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT", 
2051                         0, KEY_READ, &key);
2052  if (status == ERROR_SUCCESS)
2053    {
2054      char temp[256];
2055      DWORD length = sizeof (temp) - 1;
2056      DWORD type;
2057
2058      status = RegQueryValueEx (key, "CVSROOT", 0, &type, 
2059                                (LPBYTE) temp, &length);
2060      if (status == ERROR_SUCCESS)
2061        {
2062          cvsroot = temp;
2063          return;
2064        }
2065    }
2066#endif
2067}
2068
2069//----------------------------------------------------------
2070bool CmtSystem::get_home_directory (cmt_string& dir)
2071{
2072  bool status = false;
2073
2074#ifdef WIN32
2075  const char* homedrive = ::getenv ("HOMEDRIVE");
2076  const char* homepath = ::getenv ("HOMEPATH");
2077
2078  if ((homedrive != 0) && (homepath != 0))
2079    {
2080      dir = homedrive;
2081      dir += homepath;
2082      status = true;
2083    }
2084
2085#else
2086  const char* home_env = ::getenv ("HOME");
2087  if (home_env != 0)
2088    {
2089      dir = home_env;
2090      status = true;
2091    }
2092#endif
2093
2094  return (status);
2095}
2096
Note: See TracBrowser for help on using the repository browser.