~ubuntu-branches/ubuntu/lucid/boinc/lucid

« back to all changes in this revision

Viewing changes to client/hostinfo_unix.C

  • Committer: Bazaar Package Importer
  • Author(s): Frank S. Thomas, Frank S. Thomas
  • Date: 2008-05-31 08:02:47 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20080531080247-4ce890lp2rc768cr
Tags: 6.2.7-1
[ Frank S. Thomas ]
* New upstream release.
  - BOINC Manager: Redraw disk usage charts immediately after connecting to
    a (different) client. (closes: 463823)
* debian/copyright:
  - Added the instructions from debian/README.Debian-source about how
    repackaged BOINC tarballs can be reproduced because DevRef now
    recommends to put this here instead of in the afore-mentioned file.
  - Updated for the new release.
* Removed the obsolete debian/README.Debian-source.
* For consistency upstream renamed the core client and the command tool
  ("boinc_client" to "boinc" and "boinc_cmd" to "boinccmd"). Done the same
  in all packages and created symlinks with the old names for the binaries
  and man pages. Also added an entry in debian/boinc-client.NEWS explaining
  this change.
* debian/rules: Do not list Makefile.ins in the clean target individually,
  just remove all that can be found.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
// To view the GNU Lesser General Public License visit
16
16
// http://www.gnu.org/copyleft/lesser.html
17
17
// or write to the Free Software Foundation, Inc.,
18
 
// 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 
20
 
#include "cpp.h"
21
 
 
22
 
#include "config.h"
 
18
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 
 
20
// There is a reason that having a file called "cpp.h" that includes config.h
 
21
// and some of the C++ header files.  That reason is because there are #defines
 
22
// that alter the behiour of the standard C and C++ headers.  In this case
 
23
// we need to use the "small files" environment on some unix systems.  That
 
24
// can't be done if we include "cpp.h"
 
25
// #include "cpp.h" 
 
26
 
 
27
// copied directly from cpp.h
 
28
#if defined(_WIN32) && !defined(__CYGWIN32__)
 
29
 
 
30
#if defined(_WIN64) && defined(_M_X64)
 
31
#define HOSTTYPE    "windows_x86_64"
 
32
#define HOSTTYPEALT "windows_intelx86"
 
33
#else
 
34
#define HOSTTYPE "windows_intelx86"
 
35
#endif
 
36
 
 
37
#include "version.h"         // version numbers from autoconf
 
38
#endif
 
39
 
 
40
#if !defined(_WIN32) || defined(__CYGWIN32__)
 
41
#include "config.h"
 
42
 
 
43
// Access to binary files in /proc filesystem doesn't work in the 64bit
 
44
// files environment on some systems.  None of the functions here need 
 
45
// 64bit file functions, so we'll undefine _FILE_OFFSET_BITS and _LARGE_FILES.
 
46
#undef _FILE_OFFSET_BITS
 
47
#undef _LARGE_FILES
 
48
#include <iostream>
 
49
#include <vector>
 
50
#include <string>
 
51
#include <cstring>
 
52
#endif
 
53
 
 
54
 
 
55
#include "config.h"
 
56
 
23
57
 
24
58
#include <cstdio>
25
59
#include <cstdlib>
107
141
#include <machine/cpuconf.h>
108
142
#endif
109
143
 
 
144
// The following is intended to be true both on Linux
 
145
// and Debian GNU/kFreeBSD (see trac #521)
 
146
//
 
147
#define LINUX_LIKE_SYSTEM defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
 
148
 
110
149
// functions to get name/addr of local host
111
150
 
112
151
// Converts a int ip address to a string representation (i.e. "66.218.71.198")
134
173
    time_data = localtime( &cur_time );
135
174
    // tm_gmtoff is already adjusted for daylight savings time
136
175
    return time_data->tm_gmtoff;
137
 
#elif defined(linux)
 
176
#elif LINUX_LIKE_SYSTEM
138
177
    return -1*(__timezone);
139
178
#elif defined(__CYGWIN32__)
140
179
    return -1*(_timezone);
175
214
  CFRelease(list);
176
215
  return(retval);
177
216
 
178
 
#elif defined(linux)
 
217
#elif LINUX_LIKE_SYSTEM
179
218
    bool    retval = false;
180
219
 
181
220
    FILE* fapm = fopen("/proc/apm", "r");
182
221
    if (fapm) {         // Then we're using APM!  Yay.
183
222
 
184
 
        char    apm_driver_version[10];
 
223
        char    apm_driver_version[11];
185
224
        int     apm_major_version;
186
225
        int     apm_minor_version;
187
226
        int     apm_flags;
239
278
#endif
240
279
}
241
280
 
242
 
#ifdef linux
 
281
#if LINUX_LIKE_SYSTEM
243
282
static void parse_meminfo_linux(HOST_INFO& host) {
244
283
    char buf[256];
245
284
    double x;
451
490
    strlcpy(host.p_model, model_buf, sizeof(host.p_model));
452
491
    fclose(f);
453
492
}
454
 
#endif  // linux
 
493
#endif  // LINUX_LIKE_SYSTEM
 
494
#ifdef __FreeBSD__
 
495
#if defined(__i386__) || defined(__amd64__)
 
496
#include <sys/types.h>
 
497
#include <sys/cdefs.h>
 
498
#include <machine/cpufunc.h>
 
499
 
 
500
void use_cpuid(HOST_INFO& host) {
 
501
    u_int p[4];
 
502
    int hasMMX, hasSSE, hasSSE2, hasSSE3, has3DNow, has3DNowExt = 0;
 
503
    char capabilities[256];
 
504
 
 
505
    do_cpuid(0x0, p);
 
506
 
 
507
    if (p[0] >= 0x1) {
 
508
 
 
509
        do_cpuid(0x1, p);
 
510
 
 
511
        hasMMX  = (p[3] & (1 << 23 )) >> 23; // 0x0800000
 
512
        hasSSE  = (p[3] & (1 << 25 )) >> 25; // 0x2000000
 
513
        hasSSE2 = (p[3] & (1 << 26 )) >> 26; // 0x4000000
 
514
        hasSSE3 = (p[2] & (1 << 0 )) >> 0;
 
515
    }
 
516
 
 
517
    do_cpuid(0x80000000, p);
 
518
    if (p[0]>=0x80000001) {
 
519
        do_cpuid(0x80000001, p);
 
520
        hasMMX  |= (p[3] & (1 << 23 )) >> 23; // 0x0800000
 
521
        has3DNow    = (p[3] & (1 << 31 )) >> 31; //0x80000000
 
522
        has3DNowExt = (p[3] & (1 << 30 )) >> 30;
 
523
    }
 
524
 
 
525
    capabilities[0] = '\0';
 
526
    if (hasSSE) strncat(capabilities, "sse ", 4);
 
527
    if (hasSSE2) strncat(capabilities, "sse2 ", 5);
 
528
    if (hasSSE3) strncat(capabilities, "sse3 ", 5);
 
529
    if (has3DNow) strncat(capabilities, "3dnow ", 6);
 
530
    if (has3DNowExt) strncat(capabilities, "3dnowext ", 9);
 
531
    if (hasMMX) strncat(capabilities, "mmx ", 4);
 
532
    strip_whitespace(capabilities);
 
533
    snprintf(host.p_model, sizeof(host.p_model), "%s [] [%s]", host.p_model, capabilities);
 
534
}
 
535
#endif
 
536
#endif
455
537
 
456
538
#ifdef __APPLE__
457
539
static void get_cpu_info_maxosx(HOST_INFO& host) {
458
540
    int p_model_size = sizeof(host.p_model);
459
541
    size_t len;
460
 
#ifdef __i386__
 
542
#if defined(__i386__) || defined(__x86_64__)
461
543
    char brand_string[256];
462
544
    int family, stepping, model;
463
545
    
522
604
    get_filesystem_info(d_total, d_free);
523
605
 
524
606
///////////// p_vendor, p_model, p_features /////////////////
525
 
#ifdef linux
 
607
#if LINUX_LIKE_SYSTEM
526
608
    parse_cpuinfo_linux(*this);
527
609
#elif defined( __APPLE__)
528
610
    int mib[2];
531
613
    get_cpu_info_maxosx(*this);
532
614
#elif defined(__EMX__)
533
615
    CPU_INFO_t    cpuInfo;
534
 
    strcpy( p_vendor, cpuInfo.vendor.company);
535
 
    strcpy( p_model, cpuInfo.name.fromID);
 
616
    strlcpy( p_vendor, cpuInfo.vendor.company, sizeof(p_vendor));
 
617
    strlcpy( p_model, cpuInfo.name.fromID, sizeof(p_model));
536
618
#elif defined(HAVE_SYS_SYSCTL_H)
537
619
    int mib[2];
538
620
    size_t len;
560
642
    CPU_TYPE_TO_TEXT( (cpu_type& 0xffffffff), cpu_type_name);
561
643
    strncpy( p_model, "Alpha ", sizeof( p_model));
562
644
    strncat( p_model, cpu_type_name, (sizeof( p_model)- strlen( p_model)- 1));
 
645
    p_model[sizeof(p_model)-1]=0;
563
646
#elif defined(HAVE_SYS_SYSTEMINFO_H)
564
647
    sysinfo(SI_PLATFORM, p_vendor, sizeof(p_vendor));
565
648
    sysinfo(SI_ISALIST, p_model, sizeof(p_model));
575
658
#error Need to specify a method to get p_vendor, p_model
576
659
#endif
577
660
 
 
661
#if defined(__FreeBSD__)
 
662
#if defined(__i386__) || defined(__amd64__)
 
663
    use_cpuid(*this);
 
664
#endif
 
665
#endif
 
666
 
578
667
///////////// p_ncpus /////////////////
579
668
 
580
669
// sysconf not working on OS2
581
 
#if defined(_SC_NPROCESSORS_ONLN) && !defined(__EMX__)
 
670
#if defined(_SC_NPROCESSORS_ONLN) && !defined(__EMX__) && !defined(__APPLE__)
582
671
    p_ncpus = sysconf(_SC_NPROCESSORS_ONLN);
583
672
#elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && defined(HW_NCPU)
584
673
    // Get number of CPUs
606
695
        DosQuerySysInfo( QSV_TOTAVAILMEM, QSV_TOTAVAILMEM, &ulMem, sizeof(ulMem));
607
696
        m_swap = ulMem;
608
697
    }
609
 
#elif defined(linux)
 
698
#elif LINUX_LIKE_SYSTEM
610
699
    parse_meminfo_linux(*this);
611
700
#elif defined(_SC_USEABLE_MEMORY)
612
701
    // UnixWare
624
713
    // 4-byte value, even if passed an 8-byte buffer, and limits the returned 
625
714
    // value to 2GB when the actual RAM size is > 2GB.  The Gestalt selector 
626
715
    // gestaltPhysicalRAMSizeInMegabytes is available starting with OS 10.3.0.
627
 
    long mem_size;
 
716
    SInt32 mem_size;
628
717
    if (Gestalt(gestaltPhysicalRAMSizeInMegabytes, &mem_size)) {
629
718
        msg_printf(NULL, MSG_INTERNAL_ERROR,
630
719
            "Couldn't determine physical RAM size"
641
730
    int mem_size;
642
731
    getsysinfo( GSI_PHYSMEM, (caddr_t) &mem_size, sizeof( mem_size));
643
732
    m_nbytes = 1024.* (double)mem_size;
 
733
#elif defined(HW_PHYSMEM) 
 
734
    // for OpenBSD
 
735
    mib[0] = CTL_HW; 
 
736
    int mem_size; 
 
737
    mib[1] = HW_PHYSMEM; 
 
738
    len = sizeof(mem_size); 
 
739
    sysctl(mib, 2, &mem_size, &len, NULL, 0); 
 
740
    m_nbytes = mem_size; 
 
741
#elif defined(__FreeBSD__)
 
742
    unsigned int mem_size;
 
743
    mib[0] = CTL_HW;
 
744
    mib[1] = HW_PHYSMEM;
 
745
    len = sizeof(mem_size);
 
746
    sysctl(mib, 2, &mem_size, &len, NULL, 0);
 
747
    m_nbytes = mem_size;
644
748
#else
645
749
#error Need to specify a method to get memory size
646
750
#endif
763
867
    return stat(device, &sbuf) || (sbuf.st_atime < t);
764
868
}
765
869
 
766
 
inline bool all_tty_idle(time_t t, char *device, char first_char, int num_tty) {
 
870
static const struct dir_dev {
 
871
  char *dir;
 
872
  char *dev;
 
873
} tty_patterns[] = {
 
874
#ifdef unix
 
875
    { "/dev","tty" },
 
876
    { "/dev","pty" },
 
877
    { "/dev/pts","" },
 
878
#endif
 
879
    // add other ifdefs here as necessary.
 
880
    { NULL, NULL },
 
881
};
 
882
 
 
883
std::vector<std::string> get_tty_list() {
 
884
    // Create a list of all terminal devices on the system.
 
885
    char devname[1024];
 
886
    char fullname[1024];
 
887
    int done,i=0;
 
888
    std::vector<std::string> tty_list;
 
889
    
 
890
    do {
 
891
        DIRREF dev=dir_open(tty_patterns[i].dir);
 
892
        if (dev) {
 
893
            do {
 
894
                // get next file
 
895
                done=dir_scan(devname,dev,1024);
 
896
                // does it match our tty pattern? If so, add it to the tty list.
 
897
                if (!done && (strstr(devname,tty_patterns[i].dev) == devname)) {
 
898
                    // don't add anything starting with .
 
899
                    if (devname[0] != '.') {
 
900
                        sprintf(fullname,"%s/%s",tty_patterns[i].dir,devname);
 
901
                        tty_list.push_back(fullname);
 
902
                    }
 
903
                }
 
904
            } while (!done);
 
905
        }
 
906
        i++;
 
907
    } while (tty_patterns[i].dir != NULL);
 
908
    return tty_list;
 
909
}
 
910
       
 
911
 
 
912
inline bool all_tty_idle(time_t t) {
 
913
    static std::vector<std::string> tty_list;
767
914
    struct stat sbuf;
768
 
    char *tty_index = device + strlen(device) - 1;
769
 
    *tty_index = first_char;
770
 
    for (int i = 0; i < num_tty; i++, (*tty_index)++) {
771
 
        if (stat(device, &sbuf)) {
772
 
            // error looking at device; don't try any more
773
 
            return true;
774
 
        } else if (sbuf.st_atime >= t) {
775
 
            return false;
 
915
    unsigned int i;
 
916
 
 
917
    if (tty_list.size()==0) tty_list=get_tty_list();
 
918
    for (i=0; i<tty_list.size(); i++) {
 
919
        // ignore errors
 
920
        if (!stat(tty_list[i].c_str(), &sbuf)) {
 
921
            // printf("%s %d %d\n",tty_list[i].c_str(),sbuf.st_atime,t);
 
922
            if (sbuf.st_atime >= t) {
 
923
                return false;
 
924
            }
776
925
        }
777
926
    }
778
927
    return true;
795
944
}
796
945
 
797
946
#if !defined(HAVE_SETUTENT) || !defined(HAVE_GETUTENT)
798
 
static FILE *ufp = NULL;
799
 
static struct utmp ut;
 
947
  static FILE *ufp = NULL;
 
948
  static struct utmp ut;
800
949
 
801
 
// get next user login record
802
 
// (this is defined on everything except BSD)
803
 
//
804
 
struct utmp *getutent() {
805
 
    if (ufp == NULL) {
 
950
  // get next user login record
 
951
  // (this is defined on everything except BSD)
 
952
  //
 
953
  struct utmp *getutent() {
 
954
      if (ufp == NULL) {
806
955
#if defined(UTMP_LOCATION)
807
 
        if ((ufp = fopen(UTMP_LOCATION, "r")) == NULL) {
 
956
          if ((ufp = fopen(UTMP_LOCATION, "r")) == NULL) {
808
957
#elif defined(UTMP_FILE)
809
 
        if ((ufp = fopen(UTMP_FILE, "r")) == NULL) {
 
958
          if ((ufp = fopen(UTMP_FILE, "r")) == NULL) {
810
959
#elif defined(_PATH_UTMP)
811
 
        if ((ufp = fopen(_PATH_UTMP, "r")) == NULL) {
 
960
          if ((ufp = fopen(_PATH_UTMP, "r")) == NULL) {
812
961
#else
813
 
        if ((ufp = fopen("/etc/utmp", "r")) == NULL) {
814
 
#endif
815
 
            return((struct utmp *)NULL);
816
 
        }
817
 
    }
818
 
    do {
819
 
        if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1) {
820
 
            return((struct utmp *)NULL);
821
 
        }
822
 
    } while (ut.ut_name[0] == 0);
823
 
    return(&ut);
824
 
}
825
 
 
826
 
void setutent() {
827
 
    if (ufp != NULL) rewind(ufp);
828
 
}
829
 
#endif
830
 
 
831
 
// scan list of logged-in users, and see if they're all idle
832
 
//
833
 
inline bool all_logins_idle(time_t t) {
834
 
    struct utmp* u;
835
 
    setutent();
836
 
 
837
 
    while ((u = getutent()) != NULL) {
838
 
        if (!user_idle(t, u)) {
839
 
            return false;
840
 
        }
841
 
    }
842
 
    return true;
843
 
}
844
 
#endif
 
962
          if ((ufp = fopen("/etc/utmp", "r")) == NULL) {
 
963
#endif
 
964
              return((struct utmp *)NULL);
 
965
          }
 
966
      }
 
967
      do {
 
968
          if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1) {
 
969
              return((struct utmp *)NULL);
 
970
          }
 
971
      } while (ut.ut_name[0] == 0);
 
972
      return(&ut);
 
973
  }
 
974
 
 
975
  void setutent() {
 
976
      if (ufp != NULL) rewind(ufp);
 
977
  }
 
978
#endif
 
979
 
 
980
  // scan list of logged-in users, and see if they're all idle
 
981
  //
 
982
  inline bool all_logins_idle(time_t t) {
 
983
      struct utmp* u;
 
984
      setutent();
 
985
 
 
986
      while ((u = getutent()) != NULL) {
 
987
          if (!user_idle(t, u)) {
 
988
              return false;
 
989
          }
 
990
      }
 
991
      return true;
 
992
  }
 
993
#endif  // HAVE_UTMP_H
845
994
 
846
995
#ifdef __APPLE__
847
996
 
849
998
    bool check_all_logins, double idle_time_to_run, double *actual_idle_time
850
999
) {
851
1000
    double idleTime = 0;
852
 
    
 
1001
      
853
1002
    if (gEventHandle) {
854
 
       idleTime = NXIdleTime(gEventHandle);    
 
1003
        idleTime = NXIdleTime(gEventHandle);    
855
1004
    } else {
856
1005
        // Initialize Mac OS X idle time measurement / idle detection
857
1006
        // Do this here because NXOpenEventStatus() may not be available 
867
1016
 
868
1017
#else  // ! __APPLE__
869
1018
 
 
1019
#if LINUX_LIKE_SYSTEM
 
1020
bool interrupts_idle(time_t t) {
 
1021
    static FILE *ifp = NULL;
 
1022
    static long irq_count[256];
 
1023
    static time_t last_irq = time(NULL);
 
1024
 
 
1025
    char line[256];
 
1026
    int i = 0;
 
1027
    long ccount = 0;
 
1028
 
 
1029
    if (ifp == NULL) {
 
1030
        if ((ifp = fopen("/proc/interrupts", "r")) == NULL) {
 
1031
            return true;
 
1032
        }
 
1033
    }
 
1034
    rewind(ifp);
 
1035
    while (fgets(line, sizeof(line), ifp)) {
 
1036
        // Check for mouse, keyboard and PS/2 devices.
 
1037
        if (strcasestr(line, "mouse") != NULL ||
 
1038
            strcasestr(line, "keyboard") != NULL ||
 
1039
            strcasestr(line, "i8042") != NULL) {
 
1040
            // If any IRQ count changed, update last_irq.
 
1041
            if (sscanf(line, "%d: %ld", &i, &ccount) == 2 &&
 
1042
                irq_count[i] != ccount) {
 
1043
                last_irq = time(NULL);
 
1044
                irq_count[i] = ccount;
 
1045
            }
 
1046
        }
 
1047
    }
 
1048
    return last_irq < t;
 
1049
}
 
1050
#endif
 
1051
 
870
1052
bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run) {
871
1053
    time_t idle_time = time(0) - (long) (60 * idle_time_to_run);
872
1054
 
 
1055
#ifdef HAVE_UTMP_H
873
1056
    if (check_all_logins) {
874
 
#ifdef HAVE_UTMP_H
875
1057
        if (!all_logins_idle(idle_time)) return false;
 
1058
    }
876
1059
#endif
877
 
        if (!all_tty_idle(idle_time, "/dev/tty1", '1', 7)) return false;
878
 
    }
 
1060
 
 
1061
    if (!all_tty_idle(idle_time)) return false;
 
1062
 
 
1063
#if LINUX_LIKE_SYSTEM
 
1064
    // Check /proc/interrupts to detect keyboard or mouse activity.
 
1065
    if (!interrupts_idle(idle_time)) return false;
 
1066
#else
 
1067
    // We should find out which of the following are actually relevant
 
1068
    // on which systems (if any)
 
1069
    //
879
1070
    if (!device_idle(idle_time, "/dev/mouse")) return false;
880
1071
        // solaris, linux
 
1072
    if (!device_idle(idle_time, "/dev/input/mice")) return false;
881
1073
    if (!device_idle(idle_time, "/dev/kbd")) return false;
882
1074
        // solaris
 
1075
#endif
883
1076
    return true;
884
1077
}
885
1078
 
886
1079
#endif  // ! __APPLE__
887
1080
 
888
 
const char *BOINC_RCSID_2cf92d205b = "$Id: hostinfo_unix.C 14470 2008-01-06 08:10:13Z charlief $";
 
1081
const char *BOINC_RCSID_2cf92d205b = "$Id: hostinfo_unix.C 15275 2008-05-22 18:45:55Z romw $";