1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #define BUF_SIZ 1024
6
7 /******************
8 ** output_string **
9 *******************
10 ** Displays a string on the screen. Also, if the flag
11 ** write_to_file is set, outputs the string to the output file.
12 ** Note, this routine presumes that you've included a carriage
13 ** return at the end of the buffer.
14 */
output_string(const char * buffer,const int write_to_file,FILE * global_ofile)15 static void output_string(const char *buffer, const int write_to_file,
16 FILE *global_ofile){
17 printf("%s",buffer);
18 if(write_to_file!=0)
19 fprintf(global_ofile,"%s",buffer);
20 return;
21 }
22
23
24 /******************
25 ** removeNewLine **
26 *******************
27 ** Removes a trailing newline character if present
28 */
removeNewLine(char * s)29 static void removeNewLine(char * s) {
30 if(strlen(s)>0 && s[strlen(s)-1] == '\n') {
31 s[strlen(s)-1] = '\0';
32 }
33 }
34
35
36 /***************
37 ** runCommand **
38 ****************
39 ** Run the system command through a pipe
40 ** The pointer result must point to a pre-allocated array of at least BUF_SIZ
41 */
runCommand(const char * command,char * result)42 static void runCommand (const char *command, char *result) {
43 FILE * pipe;
44
45 pipe = popen(command, "r");
46 if(pipe == NULL) {
47 /* command failed */
48 result[0] = '\0';
49 } else {
50 if(NULL == fgets(result, BUF_SIZ, pipe)){
51 /* command failed */
52 result[0] = '\0';
53 }
54 pclose(pipe);
55 }
56 removeNewLine(result);
57 }
58
59
60 /********************
61 ** readProcCpuInfo **
62 *********************
63 ** Reads and parses /proc/cpuinfo on a Linux system
64 ** The pointers must point to pre-allocated arrays of at least BUF_SIZ
65 */
readProcCpuInfo(char * model,char * cache)66 static void readProcCpuInfo (char *model, char *cache) {
67 FILE * info;
68 char * cp;
69 int cpus = 0;
70 char * buffer_end;
71 char buffer[BUF_SIZ];
72 char vendor_id[BUF_SIZ];
73 char model_name[BUF_SIZ];
74 char cpu_MHz[BUF_SIZ];
75 int i;
76 float f;
77
78 vendor_id[0] = model_name[0] = cpu_MHz[0] = model[0] = cache[0] = '\0';
79 info = fopen("/proc/cpuinfo", "r");
80 if(info != NULL) {
81 /* command did not fail */
82 while(NULL != fgets(buffer, BUF_SIZ, info)){
83 buffer_end = buffer + strlen(buffer);
84 cp = buffer;
85 if(! strncmp(buffer, "processor", 9)) {
86 cpus++;
87 } else if(! strncmp(buffer, "vendor_id", 9)) {
88 cp+=strlen("vendor_id");
89 while(cp < buffer_end && ( *cp == ' ' || *cp == ':'|| *cp == '\t'))
90 cp++;
91 if(cp<buffer_end) {
92 strcpy(vendor_id, cp);
93 }
94 removeNewLine(vendor_id);
95 } else if(! strncmp(buffer, "model name", 10)) {
96 cp+=strlen("model name");
97 while(cp < buffer_end && ( *cp == ' ' || *cp == ':'|| *cp == '\t'))
98 cp++;
99 if(cp<buffer_end) {
100 strcpy(model_name, cp);
101 }
102 removeNewLine(model_name);
103 } else if(! strncmp(buffer, "cpu MHz", 7)) {
104 cp+=strlen("cpu MHz");
105 while(cp < buffer_end && ( *cp == ' ' || *cp == ':'|| *cp == '\t'))
106 cp++;
107 if(cp<buffer_end) {
108 strcpy(cpu_MHz, cp);
109 }
110 removeNewLine(cpu_MHz);
111 } else if(! strncmp(buffer, "cache size", 10)) {
112 cp+=strlen("cache size");
113 while(cp < buffer_end && ( *cp == ' ' || *cp == ':'|| *cp == '\t'))
114 cp++;
115 if(cp<buffer_end) {
116 strcpy(cache, cp);
117 }
118 removeNewLine(cache);
119 }
120 }
121 if(cpus>1) {
122 if (cpus==2) {
123 strcpy(model, "Dual");
124 } else {
125 sprintf(model, "%d CPU", cpus);
126 }
127 }
128 cp = model + strlen(model);
129 if(vendor_id[0] != '\0'){
130 if(cp != model){
131 *cp++ = ' ';
132 }
133 strcpy(cp, vendor_id);
134 cp += strlen(vendor_id);
135 }
136 if(model_name[0] != '\0'){
137 if(cp != model){
138 *cp++ = ' ';
139 }
140 strcpy(cp, model_name);
141 cp += strlen(model_name);
142 }
143 if(cpu_MHz[0] != '\0'){
144 if(cp != model){
145 *cp++ = ' ';
146 }
147 f = atof(cpu_MHz);
148 i = (int)(f+0.5f);
149 sprintf(cpu_MHz, "%dMHz", i);
150 strcpy(cp, cpu_MHz);
151 cp += strlen(cpu_MHz);
152 }
153 fclose(info);
154 }
155 }
156
157
158 /*************
159 ** hardware **
160 **************
161 ** Runs the system command "uname -s -r"
162 ** Reads /proc/cpuinfo if on a linux system
163 ** Writes output
164 */
hardware(const int write_to_file,FILE * global_ofile)165 void hardware(const int write_to_file, FILE *global_ofile) {
166 char buffer[BUF_SIZ];
167 char os[BUF_SIZ];
168 char model[BUF_SIZ];
169 char cache[BUF_SIZ];
170 char os_command[] = "uname -s -r";
171 #ifdef NO_UNAME
172 os[0] = '\0';
173 #else
174 runCommand(os_command, os);
175 #endif
176 if(NULL != strstr(os, "Linux")) {
177 readProcCpuInfo (model, cache);
178 } else {
179 model[0] = '\0';
180 cache[0] = '\0';
181 }
182 sprintf(buffer, "CPU : %s\n", model);
183 output_string(buffer, write_to_file, global_ofile);
184 sprintf(buffer, "L2 Cache : %s\n", cache);
185 output_string(buffer, write_to_file, global_ofile);
186 sprintf(buffer, "OS : %s\n", os);
187 output_string(buffer, write_to_file, global_ofile);
188 }
189
190
191 /************************
192 ** main for hardware.c **
193 *************************
194 ** For testing of code only
195 ** Should be commented out
196 */
197 /*
198 int main(int argc, char * argv[]) {
199 hardware(0, NULL);
200 return 0;
201 }
202 */
203