00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <errno.h>
00005
00006 #ifdef WIN32
00007 #include <direct.h>
00008 #define chdir _chdir
00009 #define rmdir _rmdir
00010
00011 #define getcwd _getcwd
00012 #define popen _popen
00013 #define pclose _pclose
00014 #define S_IFDIR _S_IFDIR
00015 #define USE_GETCWD 1
00016
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <time.h>
00020 #include <io.h>
00021 #include <windows.h>
00022
00023 #define stat _stat
00024
00025 #else
00026 #include <unistd.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <time.h>
00030 #include <dirent.h>
00031 #endif
00032
00033 #ifdef __hpux__
00034 #define USE_GETCWD 1
00035 #endif
00036
00037 #ifdef __linux__
00038 #define USE_GETCWD 1
00039 #endif
00040
00041 #ifdef USE_GETCWD
00042 char* getwd (const char* name)
00043 {
00044 char dir[256];
00045 getcwd (dir, sizeof (dir));
00046 strcpy ((char*) name, dir);
00047 return ((char*) name);
00048 }
00049 #endif
00050
00051
00052
00053 #include "cmt_system.h"
00054 #include "cmt_error.h"
00055
00056
00057 cmt_string CmtSystem::pwd ()
00058 {
00059 char buffer[256] = "";
00060 char* ptr;
00061
00062 ptr = getcwd (buffer, sizeof (buffer));
00063
00064 const char* t = &buffer[0];
00065 return ((cmt_string) t);
00066 }
00067
00068
00069 bool CmtSystem::cd (const cmt_string& dir)
00070 {
00071 if ((dir.size () == 2) && (dir[1] == ':'))
00072 {
00073 cmt_string new_dir = dir;
00074 new_dir += file_separator ();
00075 if (chdir (new_dir.c_str ()) == 0) return (true);
00076 return (false);
00077 }
00078 else
00079 {
00080 if (chdir (dir.c_str ()) == 0) return (true);
00081 return (false);
00082 }
00083 }
00084
00085
00086 void CmtSystem::basename (const cmt_string& file_name, cmt_string& result)
00087 {
00088 int pos = file_name.find_last_of ('/');
00089 if (pos == cmt_string::npos)
00090 {
00091 pos = file_name.find_last_of ('\\');
00092 }
00093
00094 if (pos == cmt_string::npos)
00095 {
00096 result = file_name;
00097 }
00098 else
00099 {
00100 file_name.substr (pos + 1, result);
00101 }
00102 }
00103
00104
00105 void CmtSystem::basename (const cmt_string& file_name,
00106 const cmt_string& ,
00107 cmt_string& result)
00108 {
00109 basename (file_name, result);
00110
00111 int pos;
00112
00113 pos = result.find_last_of ('.');
00114
00115 if (pos != cmt_string::npos)
00116 {
00117 result.erase (pos);
00118 }
00119 }
00120
00121
00122 void CmtSystem::dirname (const cmt_string& file_name, cmt_string& result)
00123 {
00124 int pos = file_name.find_last_of ('/');
00125 if (pos == cmt_string::npos)
00126 {
00127 pos = file_name.find_last_of ('\\');
00128 }
00129
00130 if (pos == cmt_string::npos)
00131 {
00132 result = "";
00133 }
00134 else
00135 {
00136 result = file_name;
00137 result.erase (pos);
00138 }
00139 }
00140
00141
00142 void CmtSystem::name (const cmt_string& file_name, cmt_string& result)
00143 {
00144 int pos;
00145
00146 result = file_name;
00147
00148
00149
00150 pos = result.find_last_of ('.');
00151
00152 if (pos != cmt_string::npos)
00153 {
00154 result.erase (pos);
00155 }
00156
00157
00158
00159 pos = result.find_last_of ('/');
00160 if (pos == cmt_string::npos)
00161 {
00162 pos = result.find_last_of ('\\');
00163 }
00164
00165 if (pos != cmt_string::npos)
00166 {
00167 result.erase (0, pos + 1);
00168 }
00169 }
00170
00171
00172 void CmtSystem::get_suffix (const cmt_string& file, cmt_string& result)
00173 {
00174 int pos = file.find_last_of ('.');
00175 int sep = file.find_last_of (file_separator ());
00176
00177 if ((pos == cmt_string::npos) || (pos < sep))
00178 {
00179 result = "";
00180 }
00181 else
00182 {
00183 file.substr (pos + 1, result);
00184 }
00185 }
00186
00187
00188 void CmtSystem::get_dot_suffix (const cmt_string& file, cmt_string& result)
00189 {
00190 int pos = file.find_last_of ('.');
00191 int sep = file.find_last_of (file_separator ());
00192
00193 if ((pos == cmt_string::npos) || (pos < sep))
00194 {
00195 result = "";
00196 }
00197 else
00198 {
00199 file.substr (pos, result);
00200 }
00201 }
00202
00203
00204 bool CmtSystem::has_prefix (const cmt_string& name)
00205 {
00206 if ((name.find ('/') == cmt_string::npos) &&
00207 (name.find ('\\') == cmt_string::npos))
00208 {
00209 return (false);
00210 }
00211
00212 return (true);
00213 }
00214
00215
00216 bool CmtSystem::absolute_path (const cmt_string& name)
00217 {
00218 if (name.size () == 0) return (false);
00219
00220 if ((name[0] == '/') ||
00221 (name[0] == '\\')) return (true);
00222
00223 if (name.size () >= 2)
00224 {
00225 if (name[1] == ':')
00226 {
00227 return (true);
00228 }
00229 }
00230 return (false);
00231 }
00232
00233
00234 bool CmtSystem::has_device (const cmt_string& name)
00235 {
00236 #ifdef WIN32
00237 if (name.size () == 0) return (false);
00238
00239 if (name.size () >= 2)
00240 {
00241 if (name[1] == ':')
00242 {
00243 return (true);
00244 }
00245 else if ((name[0] == '\\') && (name[1] == '\\'))
00246 {
00247 return (true);
00248 }
00249 }
00250 #endif
00251
00252 return (false);
00253 }
00254
00255
00256 cmt_string CmtSystem::current_branch ()
00257 {
00258 cmt_string result;
00259
00260 basename (pwd (), result);
00261
00262 return (result);
00263 }
00264
00265
00266 bool CmtSystem::test_directory (const cmt_string& name)
00267 {
00268 struct stat file_stat;
00269 int status;
00270
00271 status = stat (name.c_str (), &file_stat);
00272
00273 if (status == 0)
00274 {
00275 if ((file_stat.st_mode & S_IFDIR) == 0)
00276 {
00277 return (false);
00278 }
00279 else
00280 {
00281 return (true);
00282 }
00283 }
00284 else
00285 {
00286 return (false);
00287 }
00288 }
00289
00290
00291 bool CmtSystem::test_file (const cmt_string& name)
00292 {
00293 struct stat file_stat;
00294 int status;
00295
00296 status = stat (name.c_str (), &file_stat);
00297
00298 if (status == 0)
00299 {
00300 if ((file_stat.st_mode & S_IFDIR) == 0)
00301 {
00302 return (true);
00303 }
00304 else
00305 {
00306 return (false);
00307 }
00308 }
00309 else
00310 {
00311 return (false);
00312 }
00313 }
00314
00315
00316 bool CmtSystem::compare_files (const cmt_string& name1,
00317 const cmt_string& name2)
00318 {
00319 struct stat file_stat1;
00320 struct stat file_stat2;
00321 int status;
00322
00323 status = stat (name1.c_str (), &file_stat1);
00324
00325 if (status == 0)
00326 {
00327 if ((file_stat1.st_mode & S_IFDIR) != 0)
00328 {
00329 return (false);
00330 }
00331 }
00332 else
00333 {
00334 return (false);
00335 }
00336
00337 status = stat (name2.c_str (), &file_stat2);
00338
00339 if (status == 0)
00340 {
00341 if ((file_stat2.st_mode & S_IFDIR) != 0)
00342 {
00343 return (false);
00344 }
00345 }
00346 else
00347 {
00348 return (false);
00349 }
00350
00351 if (((int) file_stat1.st_size) != ((int) file_stat2.st_size))
00352 {
00353 return (false);
00354 }
00355
00356 static cmt_string s1;
00357 static cmt_string s2;
00358
00359 s1.read (name1);
00360 s2.read (name2);
00361
00362 return ((s1 == s2));
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372 bool CmtSystem::compare_and_update_files (const cmt_string& name1,
00373 const cmt_string& name2)
00374 {
00375 struct stat file_stat1;
00376 struct stat file_stat2;
00377 static cmt_string s1;
00378 static cmt_string s2;
00379 int status;
00380
00381 status = stat (name1.c_str (), &file_stat1);
00382
00383 if (status == 0)
00384 {
00385 if ((file_stat1.st_mode & S_IFDIR) != 0)
00386 {
00387
00388 return (false);
00389 }
00390 }
00391 else
00392 {
00393
00394 return (false);
00395 }
00396
00397 s1.read (name1);
00398
00399 status = stat (name2.c_str (), &file_stat2);
00400
00401 if (status == 0)
00402 {
00403 if ((file_stat2.st_mode & S_IFDIR) != 0)
00404 {
00405
00406 return (false);
00407 }
00408
00409 if (((int) file_stat1.st_size) == ((int) file_stat2.st_size))
00410 {
00411 s2.read (name2);
00412 if (s1 == s2)
00413 {
00414 unlink (name1);
00415 return (true);
00416 }
00417 }
00418 }
00419
00420 FILE* f = fopen (name2, "wb");
00421 if (f != NULL)
00422 {
00423 s1.write (f);
00424 fclose (f);
00425
00426 unlink (name1);
00427
00428 return (true);
00429 }
00430 else
00431 {
00432
00433
00434
00435
00436 return (false);
00437 }
00438 }
00439
00440
00441 int CmtSystem::file_size (const cmt_string& name)
00442 {
00443 struct stat file_stat;
00444 int status;
00445
00446 status = stat (name.c_str (), &file_stat);
00447
00448 if (status == 0)
00449 {
00450 return ((int) file_stat.st_size);
00451 }
00452 else
00453 {
00454 return (0);
00455 }
00456 }
00457
00458
00459 char CmtSystem::file_separator ()
00460 {
00461 #ifdef WIN32
00462 return ('\\');
00463 #else
00464 return ('/');
00465 #endif
00466 }
00467
00468
00469 char CmtSystem::path_separator ()
00470 {
00471 #ifdef WIN32
00472 return (';');
00473 #else
00474 return (':');
00475 #endif
00476 }
00477
00478
00479 char CmtSystem::command_separator ()
00480 {
00481 #ifdef WIN32
00482 return ('&');
00483 #else
00484 return (';');
00485 #endif
00486 }
00487
00488
00489 const cmt_string& CmtSystem::ev_open ()
00490 {
00491 #ifdef WIN32
00492 static const cmt_string s = "%";
00493 #else
00494 static const cmt_string s = "${";
00495 #endif
00496
00497 return (s);
00498 }
00499
00500
00501 const cmt_string& CmtSystem::ev_close ()
00502 {
00503 #ifdef WIN32
00504 static const cmt_string s = "%";
00505 #else
00506 static const cmt_string s = "}";
00507 #endif
00508
00509 return (s);
00510 }
00511
00512
00513 bool CmtSystem::create_symlink (const cmt_string& oldname,
00514 const cmt_string& newname)
00515 {
00516 ::unlink (newname.c_str ());
00517
00518 #ifdef WIN32
00519 int status = 1;
00520 #else
00521 int status = ::symlink (oldname.c_str (), newname.c_str ());
00522 #endif
00523
00524 if (status == 0) return (true);
00525 return (false);
00526 }
00527
00528
00529 bool CmtSystem::remove_file (const cmt_string& name)
00530 {
00531 if (::unlink (name) != 0)
00532 {
00533 cout << "Cannot remove file " << name << endl;
00534 return (false);
00535 }
00536
00537 return (true);
00538 }
00539
00540
00541 bool CmtSystem::remove_directory (const cmt_string& name)
00542 {
00543
00544
00545 cmt_string_vector files;
00546
00547 scan_dir (name, files);
00548
00549 for (int i = 0; i < files.size (); i++)
00550 {
00551 cmt_string& file = files[i];
00552
00553 if (test_directory (file))
00554 {
00555 if (!remove_directory (file)) return (false);
00556 }
00557 else
00558 {
00559 if (!remove_file (file)) return (false);
00560 }
00561 }
00562
00563 int status = ::rmdir (name);
00564 if (status != 0)
00565 {
00566 cout << "Cannot remove directory " << name << " errno=" << errno << endl;
00567 return (false);
00568 }
00569
00570 return (true);
00571 }
00572
00573
00574 bool CmtSystem::mkdir (const cmt_string& name)
00575 {
00576 static cmt_string_vector path_vector;
00577 int i;
00578 static cmt_string full_path;
00579 char double_fs[] = " ";
00580
00581 double_fs[0] = file_separator ();
00582 double_fs[1] = file_separator ();
00583
00584 full_path = name;
00585
00586 if (file_separator () == '/')
00587 {
00588 full_path.replace_all ("\\", file_separator ());
00589 }
00590 else
00591 {
00592 full_path.replace_all ("/", file_separator ());
00593 }
00594
00595 full_path.replace_all (double_fs, file_separator ());
00596
00597 split (full_path, file_separator (), path_vector);
00598
00599 full_path = "";
00600
00601 if (absolute_path (name))
00602 {
00603 if (!has_device (name))
00604 {
00605 full_path = file_separator ();
00606 }
00607 }
00608
00609 for (i = 0; i < path_vector.size (); i++)
00610 {
00611 const cmt_string& path = path_vector[i];
00612
00613 if (i > 0) full_path += file_separator ();
00614 full_path += path;
00615
00616 if (has_device (path)) continue;
00617
00618 if (!test_directory (full_path))
00619 {
00620 #ifdef WIN32
00621 if (::_mkdir (full_path.c_str ()) != 0)
00622 {
00623 cerr << "CMT> cannot create directory " << full_path << endl;
00624 return (false);
00625 }
00626 #else
00627 if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
00628 {
00629 cerr << "CMT> cannot create directory " << full_path << endl;
00630 return (false);
00631 }
00632 #endif
00633 }
00634 }
00635
00636 return (true);
00637 }
00638
00639
00640 void CmtSystem::scan_dir (const cmt_string& dir_name,
00641 cmt_string_vector& list)
00642 {
00643 static cmt_string dir_prefix;
00644 static cmt_string name_prefix;
00645
00646 dir_prefix = dir_name;
00647 if (dir_name == "") dir_prefix = ".";
00648
00649 if (!test_directory (dir_prefix))
00650 {
00651 dirname (dir_prefix, dir_prefix);
00652 basename (dir_name, name_prefix);
00653 }
00654 else
00655 {
00656 }
00657
00658 bool need_filter = false;
00659
00660 int wild_card;
00661
00662 wild_card = name_prefix.find ('*');
00663 if (wild_card != cmt_string::npos)
00664 {
00665 name_prefix.erase (wild_card);
00666 }
00667
00668 if (name_prefix.size () > 0)
00669 {
00670 need_filter = true;
00671 }
00672
00673 list.clear ();
00674
00675 #ifdef WIN32
00676
00677 long dir;
00678 struct _finddata_t entry;
00679
00680 static cmt_string search;
00681
00682 search = dir_prefix;
00683 search += file_separator ();
00684 search += "*";
00685
00686 dir = _findfirst (search.c_str (), &entry);
00687 if (dir > 0)
00688 {
00689 for (;;)
00690 {
00691 if ((strcmp ((char*) entry.name, ".") != 0) &&
00692 (strcmp ((char*) entry.name, "..") != 0) &&
00693 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00694 {
00695 const char* name = entry.name;
00696
00697 if (!need_filter ||
00698 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
00699 {
00700 cmt_string& name_entry = list.add ();
00701
00702 name_entry = dir_prefix;
00703 name_entry += file_separator ();
00704 name_entry += name;
00705 }
00706 }
00707
00708 int status = _findnext (dir, &entry);
00709 if (status != 0)
00710 {
00711 break;
00712 }
00713 }
00714
00715 _findclose (dir);
00716 }
00717 #else
00718
00719
00720
00721 DIR* dir = opendir (dir_prefix.c_str ());
00722
00723 struct dirent* entry;
00724
00725 if (dir != 0)
00726 {
00727 while ((entry = readdir (dir)) != 0)
00728 {
00729
00730 if (!strcmp ((char*) entry->d_name, ".")) continue;
00731 if (!strcmp ((char*) entry->d_name, "..")) continue;
00732 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00733
00734 const char* name = entry->d_name;
00735
00736 if (need_filter &&
00737 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
00738
00739
00740
00741 cmt_string& name_entry = list.add ();
00742
00743 name_entry = dir_prefix;
00744 name_entry += file_separator ();
00745 name_entry += name;
00746 }
00747
00748 closedir (dir);
00749 }
00750 #endif
00751
00752 }
00753
00754
00755 void CmtSystem::scan_dir (const cmt_string& dir_name,
00756 const cmt_regexp& expression,
00757 cmt_string_vector& list)
00758 {
00759 static cmt_string dir_prefix;
00760
00761 dir_prefix = dir_name;
00762 if (dir_name == "") dir_prefix = ".";
00763
00764 if (!test_directory (dir_prefix))
00765 {
00766 dirname (dir_prefix, dir_prefix);
00767 }
00768
00769 list.clear ();
00770
00771 #ifdef WIN32
00772
00773 long dir;
00774 struct _finddata_t entry;
00775
00776 static cmt_string search;
00777
00778 search = dir_prefix;
00779 search += file_separator ();
00780 search += "*";
00781
00782 dir = _findfirst (search.c_str (), &entry);
00783 if (dir > 0)
00784 {
00785 for (;;)
00786 {
00787 if ((entry.name[0] != '.') &&
00788 (strcmp ((char*) entry.name, ".") != 0) &&
00789 (strcmp ((char*) entry.name, "..") != 0) &&
00790 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00791 {
00792 const char* name = entry.name;
00793
00794 if (expression.match (name))
00795 {
00796 cmt_string& name_entry = list.add ();
00797
00798 name_entry = dir_prefix;
00799 name_entry += file_separator ();
00800 name_entry += name;
00801 }
00802 }
00803
00804 int status = _findnext (dir, &entry);
00805 if (status != 0)
00806 {
00807 break;
00808 }
00809 }
00810 _findclose (dir);
00811 }
00812 #else
00813
00814
00815
00816 DIR* dir = opendir (dir_prefix.c_str ());
00817
00818 struct dirent* entry;
00819
00820 if (dir != 0)
00821 {
00822 while ((entry = readdir (dir)) != 0)
00823 {
00824
00825 if (!strcmp ((char*) entry->d_name, ".")) continue;
00826 if (!strcmp ((char*) entry->d_name, "..")) continue;
00827 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00828
00829 const char* name = entry->d_name;
00830
00831 if (!expression.match (name)) continue;
00832
00833 cmt_string& name_entry = list.add ();
00834
00835 name_entry = dir_prefix;
00836 name_entry += file_separator ();
00837 name_entry += name;
00838 }
00839
00840 closedir (dir);
00841 }
00842 #endif
00843
00844 }
00845
00846
00847 CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
00848 {
00849 static cmt_string_vector result;
00850
00851 scan_dir (dir_name, result);
00852
00853 return (result);
00854 }
00855
00856
00857 const cmt_string& CmtSystem::get_cmt_root ()
00858 {
00859 static cmt_string root;
00860
00861 root = "";
00862
00863 const char* env = ::getenv ("CMTROOT");
00864 if (env != 0)
00865 {
00866 root = env;
00867
00868 dirname (root, root);
00869 dirname (root, root);
00870 return (root);
00871 }
00872
00873 #ifdef WIN32
00874 LONG status;
00875 HKEY key = 0;
00876
00877 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00878 0, KEY_READ, &key);
00879 if (status == ERROR_SUCCESS)
00880 {
00881 char temp[256];
00882 DWORD length = sizeof (temp) - 1;
00883 DWORD type;
00884
00885 status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
00886 if (status == ERROR_SUCCESS)
00887 {
00888 root = temp;
00889 return (root);
00890 }
00891 }
00892 #endif
00893
00894 return (root);
00895 }
00896
00897
00898 void CmtSystem::get_cmt_version (cmt_string& version)
00899 {
00900 version = "";
00901
00902 const char* env = ::getenv ("CMTROOT");
00903 if (env != 0)
00904 {
00905 cmt_string s = env;
00906 basename (s, version);
00907 }
00908 else
00909 {
00910 #ifdef WIN32
00911 LONG status;
00912 HKEY key = 0;
00913
00914 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00915 0, KEY_READ, &key);
00916 if (status == ERROR_SUCCESS)
00917 {
00918 char temp[256];
00919 DWORD length = sizeof (temp) - 1;
00920 DWORD type;
00921
00922 status = RegQueryValueEx (key, "version", 0, &type,
00923 (LPBYTE) temp, &length);
00924 if (status == ERROR_SUCCESS)
00925 {
00926 version = temp;
00927 }
00928 }
00929 #endif
00930 }
00931 }
00932
00933
00934 cmt_string CmtSystem::get_cmt_config ()
00935 {
00936 const char* env = ::getenv ("CMTCONFIG");
00937 if (env != 0)
00938 {
00939 return (cmt_string (env));
00940 }
00941
00942 env = ::getenv ("CMTBIN");
00943 if (env != 0)
00944 {
00945 return (cmt_string (env));
00946 }
00947
00948 #ifdef WIN32
00949 LONG status;
00950 HKEY key = 0;
00951
00952 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00953 0, KEY_READ, &key);
00954 if (status == ERROR_SUCCESS)
00955 {
00956 char temp[256];
00957 DWORD length = sizeof (temp) - 1;
00958 DWORD type;
00959
00960 status = RegQueryValueEx (key, "config", 0, &type,
00961 (LPBYTE) temp, &length);
00962 if (status == ERROR_SUCCESS)
00963 {
00964 cmt_string config (temp);
00965 return (config);
00966 }
00967 }
00968
00969 return ("VisualC");
00970 #endif
00971
00972 return ("");
00973
00974 }
00975
00976
00977 cmt_string CmtSystem::get_cmt_site ()
00978 {
00979 const char* env = ::getenv ("CMTSITE");
00980 if (env != 0)
00981 {
00982 return (cmt_string (env));
00983 }
00984
00985 #ifdef WIN32
00986 LONG status;
00987 HKEY key = 0;
00988
00989 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00990 0, KEY_READ, &key);
00991 if (status == ERROR_SUCCESS)
00992 {
00993 char temp[256];
00994 DWORD length = sizeof (temp) - 1;
00995 DWORD type;
00996
00997 status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
00998 if (status == ERROR_SUCCESS)
00999 {
01000 cmt_string site (temp);
01001 return (site);
01002 }
01003 }
01004 #endif
01005
01006 return ("");
01007 }
01008
01009
01010 void CmtSystem::get_uname (cmt_string& uname)
01011 {
01012 #ifdef WIN32
01013 uname = "WIN32";
01014 #else
01015
01016 uname = "";
01017
01018 FILE* file;
01019
01020 file = popen ("uname", "r");
01021
01022 if (file != 0)
01023 {
01024 char line[1024];
01025 char* ptr;
01026 char* nl;
01027
01028 line[0] = 0;
01029 ptr = fgets (line, sizeof (line), file);
01030 if (ptr != 0)
01031 {
01032 nl = strrchr (ptr, '\n');
01033 if (nl != 0) *nl = 0;
01034
01035 uname = ptr;
01036 }
01037 pclose (file);
01038 }
01039 #endif
01040 }
01041
01042
01043 void CmtSystem::get_hosttype (cmt_string& hosttype)
01044 {
01045 hosttype = "";
01046
01047 char* ptr;
01048
01049 ptr = ::getenv ("HOSTTYPE");
01050 if (ptr != 0)
01051 {
01052 hosttype = ptr;
01053 }
01054 }
01055
01056
01057 cmt_string CmtSystem::get_temporary_name ()
01058 {
01059 cmt_string name;
01060
01061 name = ::tmpnam (NULL);
01062
01063 return (name);
01064 }
01065
01066
01067 cmt_string CmtSystem::get_home_package ()
01068 {
01069 cmt_string name = "CMTHOME context";
01070
01071 return (name);
01072 }
01073
01074
01075 bool CmtSystem::is_home_package (const cmt_string& name,
01076 const cmt_string& version)
01077 {
01078 if ((name == "CMTHOME") &&
01079 (version == "context")) return (true);
01080
01081 return (false);
01082 }
01083
01084
01085 cmt_string CmtSystem::get_user_context_package ()
01086 {
01087 cmt_string name = "CMTUSERCONTEXT context";
01088
01089 return (name);
01090 }
01091
01092
01093 bool CmtSystem::is_user_context_package (const cmt_string& name,
01094 const cmt_string& version)
01095 {
01096 if ((name == "CMTUSERCONTEXT") &&
01097 (version == "context")) return (true);
01098
01099 return (false);
01100 }
01101
01102
01103 bool CmtSystem::testenv (const cmt_string& name)
01104 {
01105 const char* env = ::getenv (name);
01106 if (env == 0) return (false);
01107 return (true);
01108 }
01109
01110
01111 cmt_string CmtSystem::getenv (const cmt_string& name)
01112 {
01113 cmt_string result;
01114
01115 const char* env = ::getenv (name);
01116 if (env != 0)
01117 {
01118 result = env;
01119 }
01120
01121 if (name == "CMTCONFIG")
01122 {
01123 return (get_cmt_config ());
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 return (result);
01139 }
01140
01141
01142 void CmtSystem::add_cmt_path (const cmt_string& path,
01143 const cmt_string& path_source,
01144 cmt_string_vector& paths,
01145 cmt_string_vector& path_pwds,
01146 cmt_string_vector& path_sources)
01147 {
01148 cmt_string npath = path;
01149
01150 if (path == "") return;
01151
01152 npath.replace_all ("\\", file_separator ());
01153 npath.replace_all ("/", file_separator ());
01154
01155 if (!test_directory (npath))
01156 {
01157 CmtError::set (CmtError::path_not_found, npath);
01158 return;
01159 }
01160
01161 for (int i = 0; i < paths.size (); i++)
01162 {
01163 const cmt_string& p = paths[i];
01164
01165 if (p == npath) return;
01166 }
01167
01168 cmt_string& new_path = paths.add ();
01169 new_path = npath;
01170
01171 cmt_string here = pwd ();
01172 cd (npath);
01173 cmt_string& new_pwd = path_pwds.add ();
01174 new_pwd = pwd ();
01175 cd (here);
01176
01177 cmt_string& new_source = path_sources.add ();
01178 new_source = path_source;
01179 }
01180
01181
01182 static void add_cmt_paths_from_text (const cmt_string& text,
01183 const cmt_string& context,
01184 CmtSystem::cmt_string_vector& paths,
01185 CmtSystem::cmt_string_vector& path_pwds,
01186 CmtSystem::cmt_string_vector& path_sources)
01187 {
01188 static CmtSystem::cmt_string_vector path_vector;
01189 int i;
01190
01191 CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
01192
01193 for (i = 0; i < path_vector.size (); i++)
01194 {
01195 const cmt_string& path = path_vector[i];
01196
01197 CmtSystem::add_cmt_path (path, context, paths, path_pwds, path_sources);
01198 }
01199 }
01200
01201
01202 static void add_cmt_paths (const cmt_string& file_name,
01203 CmtSystem::cmt_string_vector& paths,
01204 CmtSystem::cmt_string_vector& path_pwds,
01205 CmtSystem::cmt_string_vector& path_sources)
01206 {
01207 if (!CmtSystem::test_file (file_name)) return;
01208
01209 static cmt_string text;
01210
01211 text.read (file_name);
01212
01213 int pos = text.find ("CMTPATH");
01214 if (pos == cmt_string::npos) return;
01215 pos += strlen ("CMTPATH");
01216 pos = text.find (pos, "=");
01217 if (pos == cmt_string::npos) return;
01218 pos++;
01219
01220 text.erase (0, pos);
01221
01222 int nl = text.find (pos, "\n");
01223 if (nl != cmt_string::npos) text.erase (nl);
01224
01225 add_cmt_paths_from_text (text, file_name, paths, path_pwds, path_sources);
01226 }
01227
01228
01229 void CmtSystem::get_cmt_paths (cmt_string_vector& paths,
01230 cmt_string_vector& path_pwds,
01231 cmt_string_vector& path_sources,
01232 const cmt_string& init_text)
01233 {
01234 paths.clear ();
01235 path_pwds.clear ();
01236 path_sources.clear ();
01237
01238 if (init_text != "")
01239 {
01240 add_cmt_paths_from_text (init_text, "initialization", paths, path_pwds, path_sources);
01241 }
01242
01243 #ifdef WIN32
01244 LONG status;
01245 HKEY key = 0;
01246
01247 status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
01248 0, KEY_READ, &key);
01249 if (status == ERROR_SUCCESS)
01250 {
01251 DWORD index = 0;
01252 char name[256];
01253 char temp[256];
01254
01255 for (;;)
01256 {
01257 DWORD name_length = sizeof (name) - 1;
01258 DWORD length = sizeof (temp) - 1;
01259 DWORD type;
01260 status = RegEnumValue (key, index,
01261 name, &name_length, 0, &type,
01262 (LPBYTE) temp, &length);
01263 if ((status == ERROR_SUCCESS) ||
01264 (status == 234))
01265 {
01266 const cmt_string path = temp;
01267 add_cmt_path (path, "HKEY_CURRENT_USER", paths, path_pwds, path_sources);
01268 }
01269
01270 if (status == 259)
01271 {
01272 break;
01273 }
01274
01275 index++;
01276 }
01277 }
01278
01279 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
01280 0, KEY_READ, &key);
01281 if (status == ERROR_SUCCESS)
01282 {
01283 DWORD index = 0;
01284 char name[256];
01285 char temp[256];
01286
01287 for (;;)
01288 {
01289 DWORD type;
01290 DWORD name_length = sizeof (name) - 1;
01291 DWORD length = sizeof (temp) - 1;
01292
01293
01294 status = RegEnumValue (key, index,
01295 name, &name_length, 0, &type,
01296 (LPBYTE) temp, &length);
01297 if (status != ERROR_NO_MORE_ITEMS)
01298 {
01299 const cmt_string path = temp;
01300 add_cmt_path (path, "HKEY_LOCAL_MACHINE", paths, path_pwds, path_sources);
01301 }
01302 else
01303 {
01304 break;
01305 }
01306 index++;
01307 }
01308 }
01309
01310 #endif
01311
01312
01313
01314
01315
01316
01317
01318 cmt_string rc_name;
01319
01320 const cmt_string env = CmtSystem::getenv ("CMTPATH");
01321
01322 if (env != "")
01323 {
01324 static cmt_string_vector path_vector;
01325 int i;
01326
01327 split (env, path_separator (), path_vector);
01328
01329 for (i = 0; i < path_vector.size (); i++)
01330 {
01331 const cmt_string& path = path_vector[i];
01332
01333 add_cmt_path (path, "${CMTPATH}", paths, path_pwds, path_sources);
01334 }
01335 }
01336
01337 add_cmt_paths (".cmtrc", paths, path_pwds, path_sources);
01338
01339 const char* home_env = ::getenv ("HOME");
01340 if (home_env != 0)
01341 {
01342 rc_name = home_env;
01343 rc_name += file_separator ();
01344 rc_name += ".cmtrc";
01345 add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01346 }
01347
01348 rc_name = get_cmt_root ();
01349 rc_name += file_separator ();
01350 rc_name += "CMT";
01351 rc_name += file_separator ();
01352 cmt_string version;
01353 get_cmt_version (version);
01354 rc_name += version;
01355 rc_name += file_separator ();
01356 rc_name += "mgr";
01357 rc_name += file_separator ();
01358 rc_name += ".cmtrc";
01359
01360 add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01361
01362 add_cmt_path (get_cmt_root (), "default path", paths, path_pwds, path_sources);
01363
01364 }
01365
01366
01367 int CmtSystem::execute (const cmt_string& command)
01368 {
01369
01370
01371 return (system (command.c_str ()));
01372 }
01373
01374
01375 int CmtSystem::execute (const cmt_string& command, cmt_string& output)
01376 {
01377 output = "";
01378
01379
01380
01381 FILE* f = popen (command.c_str (), "r");
01382
01383 if (f != 0)
01384 {
01385 char line[256];
01386 char* ptr;
01387
01388 while ((ptr = fgets (line, sizeof (line), f)) != NULL)
01389 {
01390 output += ptr;
01391 }
01392 pclose (f);
01393
01394 return (1);
01395 }
01396
01397 return (0);
01398 }
01399
01400
01401 bool CmtSystem::is_package_directory (const cmt_string& name)
01402 {
01403 cmt_string_vector dirs;
01404
01405 cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
01406
01407 scan_dir (name, exp, dirs);
01408
01409 if (dirs.size () == 0) return (false);
01410
01411 cmt_string req;
01412
01413 for (int i = 0; i < dirs.size (); i++)
01414 {
01415 const cmt_string& d = dirs[i];
01416
01417 req = d;
01418 req += file_separator ();
01419 req += "mgr";
01420 req += file_separator ();
01421 req += "requirements";
01422
01423 if (test_file (req)) return (true);
01424
01425 req = d;
01426 req += file_separator ();
01427 req += "cmt";
01428 req += file_separator ();
01429 req += "requirements";
01430
01431 if (test_file (req)) return (true);
01432 }
01433
01434 return (false);
01435 }
01436
01437
01438 bool CmtSystem::is_version_directory (const cmt_string& name)
01439 {
01440 int v;
01441 int r;
01442 int p;
01443
01444 return (is_version_directory (name, v, r, p));
01445 }
01446
01447
01448 bool CmtSystem::is_version_directory (const cmt_string& name,
01449 int& v,
01450 int& r,
01451 int& p)
01452 {
01453 static const cmt_string numbers = "0123456789";
01454
01455 static const int id_version = 0;
01456 static const int id_release = 1;
01457 static const int id_patch = 2;
01458
01459 cmt_string buffer;
01460
01461 enum
01462 {
01463 starting,
01464 at_key,
01465 at_number
01466 } state;
01467
01468 int id;
01469 int pos;
01470 int value;
01471
01472 v = 0;
01473 r = 0;
01474 p = 0;
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491 state = starting;
01492 id = id_version;
01493
01494 for (pos = 0; pos < name.size (); pos++)
01495 {
01496 char c = name[pos];
01497
01498 if (c == '*')
01499 {
01500
01501 switch (state)
01502 {
01503 case starting:
01504
01505 return (false);
01506 case at_key:
01507
01508 switch (id)
01509 {
01510 case id_version:
01511 v = -1;
01512 case id_release:
01513 r = -1;
01514 case id_patch:
01515 p = -1;
01516 break;
01517 }
01518 return (true);
01519 case at_number:
01520
01521 return (false);
01522 }
01523 }
01524 else if (numbers.find (c) == cmt_string::npos)
01525 {
01526
01527 switch (state)
01528 {
01529 case starting:
01530 state = at_key;
01531 break;
01532 case at_key:
01533
01534 break;
01535 case at_number:
01536 sscanf (buffer.c_str (), "%d", &value);
01537 switch (id)
01538 {
01539 case id_version:
01540 v = value;
01541 break;
01542 case id_release:
01543 r = value;
01544 break;
01545 case id_patch:
01546 p = value;
01547 break;
01548 }
01549 buffer = "";
01550 id++;
01551 state = at_key;
01552 break;
01553 }
01554 }
01555 else
01556 {
01557
01558 switch (state)
01559 {
01560 case starting:
01561
01562 return (false);
01563 case at_key:
01564
01565 buffer += c;
01566 state = at_number;
01567 break;
01568 case at_number:
01569
01570 buffer += c;
01571 break;
01572 }
01573 }
01574 }
01575
01576 switch (state)
01577 {
01578 case starting:
01579
01580 return (false);
01581 case at_key:
01582
01583 return (false);
01584 case at_number:
01585 sscanf (buffer.c_str (), "%d", &value);
01586 switch (id)
01587 {
01588 case id_version:
01589 v = value;
01590 break;
01591 case id_release:
01592 r = value;
01593 break;
01594 case id_patch:
01595 p = value;
01596 break;
01597 }
01598 id++;
01599 state = at_key;
01600 return (true);
01601 }
01602
01603 return (false);
01604 }
01605
01606
01607
01608
01609
01610 void CmtSystem::split (const cmt_string& text,
01611 const cmt_string& separators,
01612 cmt_string_vector& strings)
01613 {
01614 static char* buffer = 0;
01615 static int allocated = 0;
01616
01617 bool finished = false;
01618
01619 strings.clear ();
01620
01621 if (text.size () == 0) return;
01622
01623
01624
01625
01626
01627
01628
01629
01630 if (buffer == 0)
01631 {
01632 allocated = text.size ();
01633 buffer = (char*) malloc (allocated + 1);
01634 }
01635 else
01636 {
01637 if (text.size () > allocated)
01638 {
01639 allocated = text.size ();
01640 buffer = (char*) realloc (buffer, allocated + 1);
01641 }
01642 }
01643
01644 strcpy (buffer, text.c_str ());
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 char* current_word = buffer;
01659
01660 while (*current_word != 0)
01661 {
01662 size_t prefix_length;
01663 size_t word_length;
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675 prefix_length = strspn (current_word, separators.c_str ());
01676 if (prefix_length > 0)
01677 {
01678
01679
01680 current_word += prefix_length;
01681 }
01682
01683
01684
01685
01686
01687
01688
01689
01690 char* running_char = current_word;
01691
01692 word_length = 0;
01693
01694 for (;;)
01695 {
01696 size_t unquoted_length;
01697 size_t separator_offset;
01698
01699 unquoted_length = strcspn (running_char, "\"\'");
01700 separator_offset = strcspn (running_char, separators.c_str ());
01701
01702 if (separator_offset <= unquoted_length)
01703 {
01704
01705 running_char += separator_offset;
01706 break;
01707 }
01708
01709
01710
01711 running_char += unquoted_length;
01712
01713 char quote = running_char[0];
01714
01715
01716 {
01717 char* p = running_char;
01718 while (p[1] != 0)
01719 {
01720 *p = p[1];
01721 p++;
01722 }
01723 *p = 0;
01724 }
01725
01726
01727 {
01728 char* p = strchr (running_char, quote);
01729 if (p == 0)
01730 {
01731
01732 running_char += strlen (running_char);
01733 finished = true;
01734 break;
01735 }
01736 else
01737 {
01738 running_char = p;
01739 }
01740 }
01741
01742
01743
01744
01745 {
01746 char* p = running_char;
01747 while (p[1] != 0)
01748 {
01749 *p = p[1];
01750 p++;
01751 }
01752 *p = 0;
01753 }
01754 }
01755
01756 word_length = running_char - current_word;
01757
01758 if (current_word[word_length] == 0)
01759 {
01760 finished = true;
01761 }
01762 else
01763 {
01764 current_word[word_length] = 0;
01765 }
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 {
01796 cmt_string& s = strings.add ();
01797 s = current_word;
01798 }
01799
01800 if (finished) break;
01801
01802
01803 current_word += word_length + 1;
01804 }
01805 }
01806
01807
01808 void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
01809 {
01810 new_dir = dir;
01811
01812 compress_path (new_dir);
01813 }
01814
01815
01816
01817
01818
01819
01820
01821
01822 void CmtSystem::compress_path (cmt_string& dir)
01823 {
01824 #ifdef WIN32
01825 static const char pattern[] = "\\..\\";
01826
01827 static const char fs[] = "\\\\";
01828 #else
01829 static const char pattern[] = "/../";
01830
01831 static const char fs[] = "//";
01832 #endif
01833
01834 if (dir.size () == 0) return;
01835
01836
01837
01838
01839
01840 if (file_separator () == '/')
01841 {
01842 dir.replace_all ("\\", file_separator ());
01843 }
01844 else
01845 {
01846 dir.replace_all ("/", file_separator ());
01847 }
01848
01849 dir.replace_all (fs, file_separator ());
01850
01851 for (;;)
01852 {
01853 int pos1;
01854 int pos2;
01855
01856 pos1 = dir.find (pattern);
01857 if (pos1 == cmt_string::npos) break;
01858
01859
01860
01861
01862 cmt_string p = dir.substr (0, pos1);
01863
01864
01865
01866
01867 pos2 = p.find_last_of (file_separator ());
01868
01869 if (pos2 == cmt_string::npos) break;
01870
01871
01872
01873
01874
01875
01876
01877
01878 dir.erase (pos2, pos1 + 4 - pos2 - 1);
01879 }
01880
01881
01882 }
01883
01884
01885 cmt_string CmtSystem::now ()
01886 {
01887 cmt_string result;
01888
01889 time_t ltime;
01890 time (<ime);
01891 result = ctime (<ime);
01892
01893 result.replace_all ("\n", "");
01894
01895 return (result);
01896 }
01897
01898
01899 cmt_string CmtSystem::user ()
01900 {
01901 #ifdef _WIN32
01902 cmt_string result = getenv ("USERNAME");
01903 #else
01904 cmt_string result = getenv ("USER");
01905 #endif
01906
01907 return (result);
01908 }
01909
01910
01911 void CmtSystem::get_cvsroot (cmt_string& cvsroot)
01912 {
01913 cvsroot = "";
01914
01915 const char* env = ::getenv ("CVSROOT");
01916 if (env != 0)
01917 {
01918 cvsroot = env;
01919 return;
01920 }
01921
01922 #ifdef WIN32
01923 LONG status;
01924 HKEY key = 0;
01925
01926 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
01927 0, KEY_READ, &key);
01928 if (status == ERROR_SUCCESS)
01929 {
01930 char temp[256];
01931 DWORD length = sizeof (temp) - 1;
01932 DWORD type;
01933
01934 status = RegQueryValueEx (key, "CVSROOT", 0, &type,
01935 (LPBYTE) temp, &length);
01936 if (status == ERROR_SUCCESS)
01937 {
01938 cvsroot = temp;
01939 return;
01940 }
01941 }
01942 #endif
01943 }
01944