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
00472 void CmtSystem::reduce_file_separators (cmt_string& text)
00473 {
00474 if (file_separator () == '/')
00475 {
00476 text.replace_all ("\\", "/");
00477 text.replace_all ("//", "/");
00478 }
00479 else
00480 {
00481 text.replace_all ("/", "\\");
00482 text.replace_all ("\\\\", "\\");
00483 }
00484 }
00485
00486
00487 char CmtSystem::path_separator ()
00488 {
00489 #ifdef WIN32
00490 return (';');
00491 #else
00492 return (':');
00493 #endif
00494 }
00495
00496
00497 char CmtSystem::command_separator ()
00498 {
00499 #ifdef WIN32
00500 return ('&');
00501 #else
00502 return (';');
00503 #endif
00504 }
00505
00506
00507 const cmt_string& CmtSystem::ev_open ()
00508 {
00509 #ifdef WIN32
00510 static const cmt_string s = "%";
00511 #else
00512 static const cmt_string s = "${";
00513 #endif
00514
00515 return (s);
00516 }
00517
00518
00519 const cmt_string& CmtSystem::ev_close ()
00520 {
00521 #ifdef WIN32
00522 static const cmt_string s = "%";
00523 #else
00524 static const cmt_string s = "}";
00525 #endif
00526
00527 return (s);
00528 }
00529
00530
00531 bool CmtSystem::create_symlink (const cmt_string& oldname,
00532 const cmt_string& newname)
00533 {
00534 ::unlink (newname.c_str ());
00535
00536 #ifdef WIN32
00537 int status = 1;
00538 #else
00539 int status = ::symlink (oldname.c_str (), newname.c_str ());
00540 #endif
00541
00542 if (status == 0) return (true);
00543 return (false);
00544 }
00545
00546
00547 bool CmtSystem::remove_file (const cmt_string& name)
00548 {
00549 if (::unlink (name) != 0)
00550 {
00551 cout << "Cannot remove file " << name << endl;
00552 return (false);
00553 }
00554
00555 return (true);
00556 }
00557
00558
00559 bool CmtSystem::remove_directory (const cmt_string& name)
00560 {
00561
00562
00563 cmt_string_vector files;
00564
00565 scan_dir (name, files);
00566
00567 for (int i = 0; i < files.size (); i++)
00568 {
00569 cmt_string& file = files[i];
00570
00571 if (test_directory (file))
00572 {
00573 if (!remove_directory (file)) return (false);
00574 }
00575 else
00576 {
00577 if (!remove_file (file)) return (false);
00578 }
00579 }
00580
00581 int status = ::rmdir (name);
00582 if (status != 0)
00583 {
00584 cout << "Cannot remove directory " << name << " errno=" << errno << endl;
00585 return (false);
00586 }
00587
00588 return (true);
00589 }
00590
00591
00592 bool CmtSystem::mkdir (const cmt_string& name)
00593 {
00594 static cmt_string_vector path_vector;
00595 int i;
00596 static cmt_string full_path;
00597 char double_fs[] = " ";
00598
00599 double_fs[0] = file_separator ();
00600 double_fs[1] = file_separator ();
00601
00602 full_path = name;
00603
00604 if (file_separator () == '/')
00605 {
00606 full_path.replace_all ("\\", file_separator ());
00607 }
00608 else
00609 {
00610 full_path.replace_all ("/", file_separator ());
00611 }
00612
00613 full_path.replace_all (double_fs, file_separator ());
00614
00615 split (full_path, file_separator (), path_vector);
00616
00617 full_path = "";
00618
00619 if (absolute_path (name))
00620 {
00621 if (!has_device (name))
00622 {
00623 full_path = file_separator ();
00624 }
00625 }
00626
00627 for (i = 0; i < path_vector.size (); i++)
00628 {
00629 const cmt_string& path = path_vector[i];
00630
00631 if (i > 0) full_path += file_separator ();
00632 full_path += path;
00633
00634 if (has_device (path)) continue;
00635
00636 if (!test_directory (full_path))
00637 {
00638 #ifdef WIN32
00639 if (::_mkdir (full_path.c_str ()) != 0)
00640 {
00641 cerr << "CMT> cannot create directory " << full_path << endl;
00642 return (false);
00643 }
00644 #else
00645 if (::mkdir (full_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH ) != 0)
00646 {
00647 cerr << "CMT> cannot create directory " << full_path << endl;
00648 return (false);
00649 }
00650 #endif
00651 }
00652 }
00653
00654 return (true);
00655 }
00656
00657
00658 void CmtSystem::scan_dir (const cmt_string& dir_name,
00659 cmt_string_vector& list)
00660 {
00661 static cmt_string dir_prefix;
00662 static cmt_string name_prefix;
00663
00664 dir_prefix = dir_name;
00665 if (dir_name == "") dir_prefix = ".";
00666
00667 if (!test_directory (dir_prefix))
00668 {
00669 dirname (dir_prefix, dir_prefix);
00670 basename (dir_name, name_prefix);
00671 }
00672 else
00673 {
00674 }
00675
00676 bool need_filter = false;
00677
00678 int wild_card;
00679
00680 wild_card = name_prefix.find ('*');
00681 if (wild_card != cmt_string::npos)
00682 {
00683 name_prefix.erase (wild_card);
00684 }
00685
00686 if (name_prefix.size () > 0)
00687 {
00688 need_filter = true;
00689 }
00690
00691 list.clear ();
00692
00693 #ifdef WIN32
00694
00695 long dir;
00696 struct _finddata_t entry;
00697
00698 static cmt_string search;
00699
00700 search = dir_prefix;
00701 search += file_separator ();
00702 search += "*";
00703
00704 dir = _findfirst (search.c_str (), &entry);
00705 if (dir > 0)
00706 {
00707 for (;;)
00708 {
00709 if ((strcmp ((char*) entry.name, ".") != 0) &&
00710 (strcmp ((char*) entry.name, "..") != 0) &&
00711 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00712 {
00713 const char* name = entry.name;
00714
00715 if (!need_filter ||
00716 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) == 0))
00717 {
00718 cmt_string& name_entry = list.add ();
00719
00720 name_entry = dir_prefix;
00721 name_entry += file_separator ();
00722 name_entry += name;
00723 }
00724 }
00725
00726 int status = _findnext (dir, &entry);
00727 if (status != 0)
00728 {
00729 break;
00730 }
00731 }
00732
00733 _findclose (dir);
00734 }
00735 #else
00736
00737
00738
00739 DIR* dir = opendir (dir_prefix.c_str ());
00740
00741 struct dirent* entry;
00742
00743 if (dir != 0)
00744 {
00745 while ((entry = readdir (dir)) != 0)
00746 {
00747
00748 if (!strcmp ((char*) entry->d_name, ".")) continue;
00749 if (!strcmp ((char*) entry->d_name, "..")) continue;
00750 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00751
00752 const char* name = entry->d_name;
00753
00754 if (need_filter &&
00755 (strncmp (name, name_prefix.c_str (), name_prefix.size ()) != 0)) continue;
00756
00757
00758
00759 cmt_string& name_entry = list.add ();
00760
00761 name_entry = dir_prefix;
00762 name_entry += file_separator ();
00763 name_entry += name;
00764 }
00765
00766 closedir (dir);
00767 }
00768 #endif
00769
00770 }
00771
00772
00773 void CmtSystem::scan_dir (const cmt_string& dir_name,
00774 const cmt_regexp& expression,
00775 cmt_string_vector& list)
00776 {
00777 static cmt_string dir_prefix;
00778
00779 dir_prefix = dir_name;
00780 if (dir_name == "") dir_prefix = ".";
00781
00782 if (!test_directory (dir_prefix))
00783 {
00784 dirname (dir_prefix, dir_prefix);
00785 }
00786
00787 list.clear ();
00788
00789 #ifdef WIN32
00790
00791 long dir;
00792 struct _finddata_t entry;
00793
00794 static cmt_string search;
00795
00796 search = dir_prefix;
00797 search += file_separator ();
00798 search += "*";
00799
00800 dir = _findfirst (search.c_str (), &entry);
00801 if (dir > 0)
00802 {
00803 for (;;)
00804 {
00805 if ((entry.name[0] != '.') &&
00806 (strcmp ((char*) entry.name, ".") != 0) &&
00807 (strcmp ((char*) entry.name, "..") != 0) &&
00808 (strncmp ((char*) entry.name, ".nfs", 4) != 0))
00809 {
00810 const char* name = entry.name;
00811
00812 if (expression.match (name))
00813 {
00814 cmt_string& name_entry = list.add ();
00815
00816 name_entry = dir_prefix;
00817 name_entry += file_separator ();
00818 name_entry += name;
00819 }
00820 }
00821
00822 int status = _findnext (dir, &entry);
00823 if (status != 0)
00824 {
00825 break;
00826 }
00827 }
00828 _findclose (dir);
00829 }
00830 #else
00831
00832
00833
00834 DIR* dir = opendir (dir_prefix.c_str ());
00835
00836 struct dirent* entry;
00837
00838 if (dir != 0)
00839 {
00840 while ((entry = readdir (dir)) != 0)
00841 {
00842
00843 if (!strcmp ((char*) entry->d_name, ".")) continue;
00844 if (!strcmp ((char*) entry->d_name, "..")) continue;
00845 if (!strncmp ((char*) entry->d_name, ".nfs", 4)) continue;
00846
00847 const char* name = entry->d_name;
00848
00849 if (!expression.match (name)) continue;
00850
00851 cmt_string& name_entry = list.add ();
00852
00853 name_entry = dir_prefix;
00854 name_entry += file_separator ();
00855 name_entry += name;
00856 }
00857
00858 closedir (dir);
00859 }
00860 #endif
00861
00862 }
00863
00864
00865 CmtSystem::cmt_string_vector& CmtSystem::scan_dir (const cmt_string& dir_name)
00866 {
00867 static cmt_string_vector result;
00868
00869 scan_dir (dir_name, result);
00870
00871 return (result);
00872 }
00873
00874
00875 const cmt_string& CmtSystem::get_cmt_root ()
00876 {
00877 static cmt_string root;
00878
00879 root = "";
00880
00881 const char* env = ::getenv ("CMTROOT");
00882 if (env != 0)
00883 {
00884 root = env;
00885
00886 dirname (root, root);
00887 dirname (root, root);
00888 return (root);
00889 }
00890
00891 #ifdef WIN32
00892 LONG status;
00893 HKEY key = 0;
00894
00895 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00896 0, KEY_READ, &key);
00897 if (status == ERROR_SUCCESS)
00898 {
00899 char temp[256];
00900 DWORD length = sizeof (temp) - 1;
00901 DWORD type;
00902
00903 status = RegQueryValueEx (key, "root", 0, &type, (LPBYTE) temp, &length);
00904 if (status == ERROR_SUCCESS)
00905 {
00906 root = temp;
00907 return (root);
00908 }
00909 }
00910 #endif
00911
00912 return (root);
00913 }
00914
00915
00916 void CmtSystem::get_cmt_version (cmt_string& version)
00917 {
00918 version = "";
00919
00920 const char* env = ::getenv ("CMTROOT");
00921 if (env != 0)
00922 {
00923 cmt_string s = env;
00924 basename (s, version);
00925 }
00926 else
00927 {
00928 #ifdef WIN32
00929 LONG status;
00930 HKEY key = 0;
00931
00932 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00933 0, KEY_READ, &key);
00934 if (status == ERROR_SUCCESS)
00935 {
00936 char temp[256];
00937 DWORD length = sizeof (temp) - 1;
00938 DWORD type;
00939
00940 status = RegQueryValueEx (key, "version", 0, &type,
00941 (LPBYTE) temp, &length);
00942 if (status == ERROR_SUCCESS)
00943 {
00944 version = temp;
00945 }
00946 }
00947 #endif
00948 }
00949 }
00950
00951
00952 cmt_string CmtSystem::get_cmt_config ()
00953 {
00954 const char* env = ::getenv ("CMTCONFIG");
00955 if (env != 0)
00956 {
00957 return (cmt_string (env));
00958 }
00959
00960 env = ::getenv ("CMTBIN");
00961 if (env != 0)
00962 {
00963 return (cmt_string (env));
00964 }
00965
00966 #ifdef WIN32
00967 LONG status;
00968 HKEY key = 0;
00969
00970 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
00971 0, KEY_READ, &key);
00972 if (status == ERROR_SUCCESS)
00973 {
00974 char temp[256];
00975 DWORD length = sizeof (temp) - 1;
00976 DWORD type;
00977
00978 status = RegQueryValueEx (key, "config", 0, &type,
00979 (LPBYTE) temp, &length);
00980 if (status == ERROR_SUCCESS)
00981 {
00982 cmt_string config (temp);
00983 return (config);
00984 }
00985 }
00986
00987 return ("VisualC");
00988 #endif
00989
00990 return ("");
00991
00992 }
00993
00994
00995 cmt_string CmtSystem::get_cmt_site ()
00996 {
00997 const char* env = ::getenv ("CMTSITE");
00998 if (env != 0)
00999 {
01000 return (cmt_string (env));
01001 }
01002
01003 #ifdef WIN32
01004 LONG status;
01005 HKEY key = 0;
01006
01007 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
01008 0, KEY_READ, &key);
01009 if (status == ERROR_SUCCESS)
01010 {
01011 char temp[256];
01012 DWORD length = sizeof (temp) - 1;
01013 DWORD type;
01014
01015 status = RegQueryValueEx (key, "site", 0, &type, (LPBYTE) temp, &length);
01016 if (status == ERROR_SUCCESS)
01017 {
01018 cmt_string site (temp);
01019 return (site);
01020 }
01021 }
01022 #endif
01023
01024 return ("");
01025 }
01026
01027
01028 void CmtSystem::get_uname (cmt_string& uname)
01029 {
01030 #ifdef WIN32
01031 uname = "WIN32";
01032 #else
01033
01034 uname = "";
01035
01036 FILE* file;
01037
01038 file = popen ("uname", "r");
01039
01040 if (file != 0)
01041 {
01042 char line[1024];
01043 char* ptr;
01044 char* nl;
01045
01046 line[0] = 0;
01047 ptr = fgets (line, sizeof (line), file);
01048 if (ptr != 0)
01049 {
01050 nl = strrchr (ptr, '\n');
01051 if (nl != 0) *nl = 0;
01052
01053 uname = ptr;
01054 }
01055 pclose (file);
01056 }
01057 #endif
01058 }
01059
01060
01061 void CmtSystem::get_hosttype (cmt_string& hosttype)
01062 {
01063 hosttype = "";
01064
01065 char* ptr;
01066
01067 ptr = ::getenv ("HOSTTYPE");
01068 if (ptr != 0)
01069 {
01070 hosttype = ptr;
01071 }
01072 }
01073
01074
01075 cmt_string CmtSystem::get_temporary_name ()
01076 {
01077 cmt_string name;
01078
01079 name = ::tmpnam (NULL);
01080
01081 return (name);
01082 }
01083
01084
01085 cmt_string CmtSystem::get_home_package ()
01086 {
01087 cmt_string name = "CMTHOME context";
01088
01089 return (name);
01090 }
01091
01092
01093 bool CmtSystem::is_home_package (const cmt_string& name,
01094 const cmt_string& version)
01095 {
01096 if ((name == "CMTHOME") &&
01097 (version == "context")) return (true);
01098
01099 return (false);
01100 }
01101
01102
01103 cmt_string CmtSystem::get_user_context_package ()
01104 {
01105 cmt_string name = "CMTUSERCONTEXT context";
01106
01107 return (name);
01108 }
01109
01110
01111 bool CmtSystem::is_user_context_package (const cmt_string& name,
01112 const cmt_string& version)
01113 {
01114 if ((name == "CMTUSERCONTEXT") &&
01115 (version == "context")) return (true);
01116
01117 return (false);
01118 }
01119
01120
01121 bool CmtSystem::testenv (const cmt_string& name)
01122 {
01123 const char* env = ::getenv (name);
01124 if (env == 0) return (false);
01125 return (true);
01126 }
01127
01128
01129 cmt_string CmtSystem::getenv (const cmt_string& name)
01130 {
01131 cmt_string result;
01132
01133 const char* env = ::getenv (name);
01134 if (env != 0)
01135 {
01136 result = env;
01137 }
01138
01139 if (name == "CMTCONFIG")
01140 {
01141 return (get_cmt_config ());
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156 return (result);
01157 }
01158
01159
01160 void CmtSystem::add_cmt_path (const cmt_string& path,
01161 const cmt_string& path_source,
01162 cmt_string_vector& paths,
01163 cmt_string_vector& path_pwds,
01164 cmt_string_vector& path_sources)
01165 {
01166 cmt_string npath = path;
01167
01168 if (path == "") return;
01169
01170 npath.replace_all ("\\", file_separator ());
01171 npath.replace_all ("/", file_separator ());
01172
01173 if (!test_directory (npath))
01174 {
01175 CmtError::set (CmtError::path_not_found, npath);
01176 return;
01177 }
01178
01179 for (int i = 0; i < paths.size (); i++)
01180 {
01181 const cmt_string& p = paths[i];
01182
01183 if (p == npath) return;
01184 }
01185
01186 cmt_string& new_path = paths.add ();
01187 new_path = npath;
01188
01189 cmt_string here = pwd ();
01190 cd (npath);
01191 cmt_string& new_pwd = path_pwds.add ();
01192 new_pwd = pwd ();
01193 cd (here);
01194
01195 cmt_string& new_source = path_sources.add ();
01196 new_source = path_source;
01197 }
01198
01199
01200 static void add_cmt_paths_from_text (const cmt_string& text,
01201 const cmt_string& context,
01202 CmtSystem::cmt_string_vector& paths,
01203 CmtSystem::cmt_string_vector& path_pwds,
01204 CmtSystem::cmt_string_vector& path_sources)
01205 {
01206 static CmtSystem::cmt_string_vector path_vector;
01207 int i;
01208
01209 CmtSystem::split (text, CmtSystem::path_separator (), path_vector);
01210
01211 for (i = 0; i < path_vector.size (); i++)
01212 {
01213 const cmt_string& path = path_vector[i];
01214
01215 CmtSystem::add_cmt_path (path, context, paths, path_pwds, path_sources);
01216 }
01217 }
01218
01219
01220 static void add_cmt_paths (const cmt_string& file_name,
01221 CmtSystem::cmt_string_vector& paths,
01222 CmtSystem::cmt_string_vector& path_pwds,
01223 CmtSystem::cmt_string_vector& path_sources)
01224 {
01225 if (!CmtSystem::test_file (file_name)) return;
01226
01227 static cmt_string text;
01228
01229 text.read (file_name);
01230
01231 int pos = text.find ("CMTPATH");
01232 if (pos == cmt_string::npos) return;
01233 pos += strlen ("CMTPATH");
01234 pos = text.find (pos, "=");
01235 if (pos == cmt_string::npos) return;
01236 pos++;
01237
01238 text.erase (0, pos);
01239
01240 int nl = text.find (pos, "\n");
01241 if (nl != cmt_string::npos) text.erase (nl);
01242
01243 add_cmt_paths_from_text (text, file_name, paths, path_pwds, path_sources);
01244 }
01245
01246
01247 void CmtSystem::get_cmt_paths (cmt_string_vector& paths,
01248 cmt_string_vector& path_pwds,
01249 cmt_string_vector& path_sources,
01250 const cmt_string& init_text)
01251 {
01252 paths.clear ();
01253 path_pwds.clear ();
01254 path_sources.clear ();
01255
01256 if (init_text != "")
01257 {
01258 add_cmt_paths_from_text (init_text, "initialization", paths, path_pwds, path_sources);
01259 }
01260
01261 #ifdef WIN32
01262 LONG status;
01263 HKEY key = 0;
01264
01265 status = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\CMT\\path",
01266 0, KEY_READ, &key);
01267 if (status == ERROR_SUCCESS)
01268 {
01269 DWORD index = 0;
01270 char name[256];
01271 char temp[256];
01272
01273 for (;;)
01274 {
01275 DWORD name_length = sizeof (name) - 1;
01276 DWORD length = sizeof (temp) - 1;
01277 DWORD type;
01278 status = RegEnumValue (key, index,
01279 name, &name_length, 0, &type,
01280 (LPBYTE) temp, &length);
01281 if ((status == ERROR_SUCCESS) ||
01282 (status == 234))
01283 {
01284 const cmt_string path = temp;
01285 add_cmt_path (path, "HKEY_CURRENT_USER", paths, path_pwds, path_sources);
01286 }
01287
01288 if (status == 259)
01289 {
01290 break;
01291 }
01292
01293 index++;
01294 }
01295 }
01296
01297 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT\\path",
01298 0, KEY_READ, &key);
01299 if (status == ERROR_SUCCESS)
01300 {
01301 DWORD index = 0;
01302 char name[256];
01303 char temp[256];
01304
01305 for (;;)
01306 {
01307 DWORD type;
01308 DWORD name_length = sizeof (name) - 1;
01309 DWORD length = sizeof (temp) - 1;
01310
01311
01312 status = RegEnumValue (key, index,
01313 name, &name_length, 0, &type,
01314 (LPBYTE) temp, &length);
01315 if (status != ERROR_NO_MORE_ITEMS)
01316 {
01317 const cmt_string path = temp;
01318 add_cmt_path (path, "HKEY_LOCAL_MACHINE", paths, path_pwds, path_sources);
01319 }
01320 else
01321 {
01322 break;
01323 }
01324 index++;
01325 }
01326 }
01327
01328 #endif
01329
01330
01331
01332
01333
01334
01335
01336 cmt_string rc_name;
01337
01338 const cmt_string env = CmtSystem::getenv ("CMTPATH");
01339
01340 if (env != "")
01341 {
01342 static cmt_string_vector path_vector;
01343 int i;
01344
01345 split (env, path_separator (), path_vector);
01346
01347 for (i = 0; i < path_vector.size (); i++)
01348 {
01349 const cmt_string& path = path_vector[i];
01350
01351 add_cmt_path (path, "${CMTPATH}", paths, path_pwds, path_sources);
01352 }
01353 }
01354
01355 add_cmt_paths (".cmtrc", paths, path_pwds, path_sources);
01356
01357 const char* home_env = ::getenv ("HOME");
01358 if (home_env != 0)
01359 {
01360 rc_name = home_env;
01361 rc_name += file_separator ();
01362 rc_name += ".cmtrc";
01363 add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01364 }
01365
01366 rc_name = get_cmt_root ();
01367 rc_name += file_separator ();
01368 rc_name += "CMT";
01369 rc_name += file_separator ();
01370 cmt_string version;
01371 get_cmt_version (version);
01372 rc_name += version;
01373 rc_name += file_separator ();
01374 rc_name += "mgr";
01375 rc_name += file_separator ();
01376 rc_name += ".cmtrc";
01377
01378 add_cmt_paths (rc_name, paths, path_pwds, path_sources);
01379
01380 add_cmt_path (get_cmt_root (), "default path", paths, path_pwds, path_sources);
01381
01382 }
01383
01384
01385 int CmtSystem::execute (const cmt_string& command)
01386 {
01387
01388
01389 return (system (command.c_str ()));
01390 }
01391
01392
01393 int CmtSystem::execute (const cmt_string& command, cmt_string& output)
01394 {
01395 output = "";
01396
01397
01398
01399 FILE* f = popen (command.c_str (), "r");
01400
01401 if (f != 0)
01402 {
01403 char line[256];
01404 char* ptr;
01405
01406 while ((ptr = fgets (line, sizeof (line), f)) != NULL)
01407 {
01408 output += ptr;
01409 }
01410 pclose (f);
01411
01412 return (1);
01413 }
01414
01415 return (0);
01416 }
01417
01418
01419 bool CmtSystem::is_package_directory (const cmt_string& name)
01420 {
01421 cmt_string_vector dirs;
01422
01423 cmt_regexp exp ("^[a-zA-Z.][0-9]+([a-zA-Z.][0-9]+([a-zA-Z.][0-9]+)?)?");
01424
01425 scan_dir (name, exp, dirs);
01426
01427 cmt_string req;
01428
01429 req = name;
01430 req += file_separator ();
01431 req += "cmt";
01432 req += file_separator ();
01433 req += "requirements";
01434
01435 if (test_file (req)) return (true);
01436
01437 if (dirs.size () == 0)
01438 {
01439 return (false);
01440 }
01441
01442 for (int i = 0; i < dirs.size (); i++)
01443 {
01444 const cmt_string& d = dirs[i];
01445
01446 req = d;
01447 req += file_separator ();
01448 req += "mgr";
01449 req += file_separator ();
01450 req += "requirements";
01451
01452 if (test_file (req)) return (true);
01453
01454 req = d;
01455 req += file_separator ();
01456 req += "cmt";
01457 req += file_separator ();
01458 req += "requirements";
01459
01460 if (test_file (req)) return (true);
01461 }
01462
01463 return (false);
01464 }
01465
01466
01467 bool CmtSystem::is_version_directory (const cmt_string& name)
01468 {
01469 int v;
01470 int r;
01471 int p;
01472
01473 return (is_version_directory (name, v, r, p));
01474 }
01475
01476
01477 bool CmtSystem::is_version_directory (const cmt_string& name,
01478 int& v,
01479 int& r,
01480 int& p)
01481 {
01482 static const cmt_string numbers = "0123456789";
01483
01484 static const int id_version = 0;
01485 static const int id_release = 1;
01486 static const int id_patch = 2;
01487
01488 cmt_string buffer;
01489
01490 enum
01491 {
01492 starting,
01493 at_key,
01494 at_number
01495 } state;
01496
01497 int id;
01498 int pos;
01499 int value;
01500
01501 v = 0;
01502 r = 0;
01503 p = 0;
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 state = starting;
01521 id = id_version;
01522
01523 for (pos = 0; pos < name.size (); pos++)
01524 {
01525 char c = name[pos];
01526
01527 if (c == '*')
01528 {
01529
01530 switch (state)
01531 {
01532 case starting:
01533
01534 return (false);
01535 case at_key:
01536
01537 switch (id)
01538 {
01539 case id_version:
01540 v = -1;
01541 case id_release:
01542 r = -1;
01543 case id_patch:
01544 p = -1;
01545 break;
01546 }
01547 return (true);
01548 case at_number:
01549
01550 return (false);
01551 }
01552 }
01553 else if (numbers.find (c) == cmt_string::npos)
01554 {
01555
01556 switch (state)
01557 {
01558 case starting:
01559 state = at_key;
01560 break;
01561 case at_key:
01562
01563 break;
01564 case at_number:
01565 sscanf (buffer.c_str (), "%d", &value);
01566 switch (id)
01567 {
01568 case id_version:
01569 v = value;
01570 break;
01571 case id_release:
01572 r = value;
01573 break;
01574 case id_patch:
01575 p = value;
01576 break;
01577 }
01578 buffer = "";
01579 id++;
01580 state = at_key;
01581 break;
01582 }
01583 }
01584 else
01585 {
01586
01587 switch (state)
01588 {
01589 case starting:
01590
01591 return (false);
01592 case at_key:
01593
01594 buffer += c;
01595 state = at_number;
01596 break;
01597 case at_number:
01598
01599 buffer += c;
01600 break;
01601 }
01602 }
01603 }
01604
01605 switch (state)
01606 {
01607 case starting:
01608
01609 return (false);
01610 case at_key:
01611
01612 return (false);
01613 case at_number:
01614 sscanf (buffer.c_str (), "%d", &value);
01615 switch (id)
01616 {
01617 case id_version:
01618 v = value;
01619 break;
01620 case id_release:
01621 r = value;
01622 break;
01623 case id_patch:
01624 p = value;
01625 break;
01626 }
01627 id++;
01628 state = at_key;
01629 return (true);
01630 }
01631
01632 return (false);
01633 }
01634
01635
01636
01637
01638
01639 void CmtSystem::split (const cmt_string& text,
01640 const cmt_string& separators,
01641 cmt_string_vector& strings)
01642 {
01643 static char* buffer = 0;
01644 static int allocated = 0;
01645
01646 bool finished = false;
01647
01648 strings.clear ();
01649
01650 if (text.size () == 0) return;
01651
01652
01653
01654
01655
01656
01657
01658
01659 if (buffer == 0)
01660 {
01661 allocated = text.size ();
01662 buffer = (char*) malloc (allocated + 1);
01663 }
01664 else
01665 {
01666 if (text.size () > allocated)
01667 {
01668 allocated = text.size ();
01669 buffer = (char*) realloc (buffer, allocated + 1);
01670 }
01671 }
01672
01673 strcpy (buffer, text.c_str ());
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687 char* current_word = buffer;
01688
01689 while (*current_word != 0)
01690 {
01691 size_t prefix_length;
01692 size_t word_length;
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704 prefix_length = strspn (current_word, separators.c_str ());
01705 if (prefix_length > 0)
01706 {
01707
01708
01709 current_word += prefix_length;
01710 }
01711
01712
01713
01714
01715
01716
01717
01718
01719 char* running_char = current_word;
01720
01721 word_length = 0;
01722
01723 for (;;)
01724 {
01725 size_t unquoted_length;
01726 size_t separator_offset;
01727
01728 unquoted_length = strcspn (running_char, "\"\'");
01729 separator_offset = strcspn (running_char, separators.c_str ());
01730
01731 if (separator_offset <= unquoted_length)
01732 {
01733
01734 running_char += separator_offset;
01735 break;
01736 }
01737
01738
01739
01740 running_char += unquoted_length;
01741
01742 char quote = running_char[0];
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 {
01757 char* p = strchr (running_char, quote);
01758 if (p == 0)
01759 {
01760
01761 running_char += strlen (running_char);
01762 finished = true;
01763 break;
01764 }
01765 else
01766 {
01767 running_char = p;
01768 }
01769 }
01770
01771
01772
01773
01774 {
01775 char* p = running_char;
01776 while (p[1] != 0)
01777 {
01778 *p = p[1];
01779 p++;
01780 }
01781 *p = 0;
01782 }
01783 }
01784
01785 word_length = running_char - current_word;
01786
01787 if (current_word[word_length] == 0)
01788 {
01789 finished = true;
01790 }
01791 else
01792 {
01793 current_word[word_length] = 0;
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824 {
01825 cmt_string& s = strings.add ();
01826 s = current_word;
01827 }
01828
01829 if (finished) break;
01830
01831
01832 current_word += word_length + 1;
01833 }
01834 }
01835
01836
01837 void CmtSystem::compress_path (const cmt_string& dir, cmt_string& new_dir)
01838 {
01839 new_dir = dir;
01840
01841 compress_path (new_dir);
01842 }
01843
01844
01845
01846
01847
01848
01849
01850
01851 void CmtSystem::compress_path (cmt_string& dir)
01852 {
01853 #ifdef WIN32
01854 static const char pattern[] = "\\..\\";
01855
01856 static const char fs[] = "\\\\";
01857 #else
01858 static const char pattern[] = "/../";
01859
01860 static const char fs[] = "//";
01861 #endif
01862
01863 if (dir.size () == 0) return;
01864
01865
01866
01867
01868
01869 if (file_separator () == '/')
01870 {
01871 dir.replace_all ("\\", file_separator ());
01872 }
01873 else
01874 {
01875 dir.replace_all ("/", file_separator ());
01876 }
01877
01878 dir.replace_all (fs, file_separator ());
01879
01880 for (;;)
01881 {
01882 int pos1;
01883 int pos2;
01884
01885 pos1 = dir.find (pattern);
01886 if (pos1 == cmt_string::npos) break;
01887
01888
01889
01890
01891 cmt_string p = dir.substr (0, pos1);
01892
01893
01894
01895
01896 pos2 = p.find_last_of (file_separator ());
01897
01898 if (pos2 == cmt_string::npos) break;
01899
01900
01901
01902
01903
01904
01905
01906
01907 dir.erase (pos2, pos1 + 4 - pos2 - 1);
01908 }
01909
01910
01911 }
01912
01913
01914 cmt_string CmtSystem::now ()
01915 {
01916 cmt_string result;
01917
01918 time_t ltime;
01919 time (<ime);
01920 result = ctime (<ime);
01921
01922 result.replace_all ("\n", "");
01923
01924 return (result);
01925 }
01926
01927
01928 cmt_string CmtSystem::user ()
01929 {
01930 #ifdef _WIN32
01931 cmt_string result = getenv ("USERNAME");
01932 #else
01933 cmt_string result = getenv ("USER");
01934 #endif
01935
01936 return (result);
01937 }
01938
01939
01940 void CmtSystem::get_cvsroot (cmt_string& cvsroot)
01941 {
01942 cvsroot = "";
01943
01944 const char* env = ::getenv ("CVSROOT");
01945 if (env != 0)
01946 {
01947 cvsroot = env;
01948 return;
01949 }
01950
01951 #ifdef WIN32
01952 LONG status;
01953 HKEY key = 0;
01954
01955 status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, "Software\\CMT",
01956 0, KEY_READ, &key);
01957 if (status == ERROR_SUCCESS)
01958 {
01959 char temp[256];
01960 DWORD length = sizeof (temp) - 1;
01961 DWORD type;
01962
01963 status = RegQueryValueEx (key, "CVSROOT", 0, &type,
01964 (LPBYTE) temp, &length);
01965 if (status == ERROR_SUCCESS)
01966 {
01967 cvsroot = temp;
01968 return;
01969 }
01970 }
01971 #endif
01972 }
01973