~ubuntu-branches/ubuntu/vivid/xfce4-sensors-plugin/vivid

« back to all changes in this revision

Viewing changes to .pc/01_fix-hdds-detection-linux-3.x.patch/lib/hddtemp.c

  • Committer: Package Import Robot
  • Author(s): Lionel Le Folgoc
  • Date: 2011-12-28 21:14:07 UTC
  • Revision ID: package-import@ubuntu.com-20111228211407-1n2ybb1xyurmxziq
Tags: 1.2.3-2
* debian/patches:
  - 01_fix-hdds-detection-linux-3.x.patch: fix incorrect test with linux
    3.x.                                                      closes: #640052

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id$ */
 
2
/*  Copyright 2004-2010 Fabian Nowak (timystery@arcor.de)
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
17
 */
 
18
 
 
19
/* Note for programmers and editors: Try to use 4 spaces instead of Tab! */
 
20
 
 
21
#ifdef HAVE_CONFIG_H
 
22
# include <config.h>
 
23
#endif
 
24
 
 
25
/* Package includes */
 
26
#include <hddtemp.h>
 
27
#include <middlelayer.h>
 
28
#include <types.h>
 
29
#include <sensors-interface-common.h>
 
30
 
 
31
/* Gtk/Glib includes */
 
32
#include <glib.h>
 
33
/* #include <glib/garray.h>
 
34
#include <glib/gdir.h>
 
35
#include <glib/gerror.h>
 
36
#include <glib/gmem.h>
 
37
#include <glib/gmessages.h>
 
38
#include <glib/gprintf.h>
 
39
#include <glib/gspawn.h>
 
40
#include <glib/gstrfuncs.h> */
 
41
#include <gtk/gtk.h>
 
42
/* #include <gtk/gtkcheckbutton.h>
 
43
#include <gtk/gtkmessagedialog.h>
 
44
#include <gtk/gtklabel.h>
 
45
#include <gtk/gtkstock.h> */
 
46
 
 
47
/* Global includes */
 
48
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
49
#include <libnotify/notify.h>
 
50
#endif
 
51
/* #include <stdio.h> */
 
52
#include <stdlib.h>
 
53
#include <string.h>
 
54
 
 
55
#include <sys/types.h>
 
56
#include <sys/socket.h>
 
57
#include <netinet/in.h>
 
58
#include <netdb.h>
 
59
 
 
60
#include <sys/utsname.h>
 
61
 
 
62
#include <unistd.h>
 
63
 
 
64
#ifdef HAVE_NETCAT
 
65
# include "helpers.c"
 
66
# ifndef NETCAT_PATH
 
67
#  define NETCAT_PATH "/bin/netcat"
 
68
# endif
 
69
# define DOUBLE_DELIMITER "||"
 
70
# define SINGLE_DELIMITER "|"
 
71
#endif
 
72
 
 
73
#ifndef HDDTEMP_PORT
 
74
# define HDDTEMP_PORT 7634
 
75
#endif
 
76
 
 
77
 
 
78
#define REPLY_MAX_SIZE 512
 
79
 
 
80
 
 
81
/* forward declaration for GCC 4.3 -Wall */
 
82
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
83
void notification_suppress_messages (NotifyNotification *n, gchar *action, gpointer *data);
 
84
#endif
 
85
 
 
86
void quick_message_notify (gchar *message);
 
87
void quick_message (gchar *message);
 
88
void read_disks_netcat (t_chip *chip);
 
89
void read_disks_linux26 (t_chip *chip);
 
90
int get_hddtemp_d_str (char *buffer, size_t bufsize);
 
91
void read_disks_fallback (t_chip *chip);
 
92
void remove_unmonitored_drives (t_chip *chip, gboolean *suppressmessage);
 
93
void populate_detected_drives (t_chip *chip);
 
94
 
 
95
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
96
void
 
97
notification_suppress_messages (NotifyNotification *n, gchar *action, gpointer *data)
 
98
{
 
99
    if (strcmp(action, "confirmed")!=0)
 
100
        return;
 
101
 
 
102
    /* FIXME: Use channels or propagate private object or use static global variable */
 
103
}
 
104
 
 
105
void quick_message_notify (gchar *message)
 
106
{
 
107
    NotifyNotification *nn;
 
108
    gchar *summary, *body, *icon;
 
109
    GError *error = NULL;
 
110
 
 
111
    summary = "Hddtemp Information";
 
112
    body = message;
 
113
    icon = "xfce-sensors";
 
114
 
 
115
    if (!notify_is_initted())
 
116
        notify_init(PACKAGE); /* NOTIFY_APPNAME */
 
117
 
 
118
#ifdef HAVE_LIBNOTIFY7
 
119
    nn = notify_notification_new (summary, body, icon);
 
120
#elif HAVE_LIBNOTIFY4
 
121
    nn = notify_notification_new (summary, body, icon, NULL);
 
122
#endif
 
123
    /* FIXME: Use channels or propagate private object or use static global variable */
 
124
    //notify_notification_add_action (nn,
 
125
                            //"confirmed",
 
126
                            //_("Don't show this message again"),
 
127
                            //(NotifyActionCallback) notification_suppress_messages,
 
128
                            //NULL);
 
129
    notify_notification_show(nn, &error);
 
130
}
 
131
#else
 
132
void quick_message_dialog (gchar *message)
 
133
{
 
134
 
 
135
    GtkWidget *dialog;  /*, *label; */
 
136
 
 
137
    TRACE ("enters quick_message");
 
138
 
 
139
    dialog = gtk_message_dialog_new (NULL,
 
140
                                  GTK_DIALOG_DESTROY_WITH_PARENT,
 
141
                                  GTK_MESSAGE_INFO,
 
142
                                  GTK_BUTTONS_CLOSE,
 
143
                                  message);
 
144
 
 
145
    /* dialog = gtk_dialog_new_with_buttons (_("Could not run \"hddtemp\""),
 
146
                                         NULL, 0, // GTK DIALOG NO MODAL ;-)
 
147
                                         GTK_STOCK_CLOSE, GTK_RESPONSE_NONE,
 
148
                                         NULL);
 
149
    label = gtk_label_new (message);
 
150
    gtk_label_set_line_wrap (GTK_LABEL(label), TRUE);
 
151
    gtk_label_set_width_chars (GTK_LABEL(label), 60); */
 
152
 
 
153
    g_signal_connect_swapped (dialog, "response",
 
154
                             G_CALLBACK (gtk_widget_destroy), dialog);
 
155
 
 
156
    /*
 
157
    gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
 
158
    gtk_widget_show_all (dialog); */
 
159
    gtk_dialog_run(GTK_DIALOG(dialog));
 
160
 
 
161
    TRACE ("leaves quick_message");
 
162
}
 
163
 
 
164
gboolean quick_message_with_checkbox (gchar *message, gchar *checkboxtext) {
 
165
 
 
166
    GtkWidget *dialog, *checkbox;  /*, *label; */
 
167
    gboolean is_active;
 
168
 
 
169
    TRACE ("enters quick_message");
 
170
 
 
171
    dialog = gtk_message_dialog_new (NULL,
 
172
                                  0, /* GTK_DIALOG_DESTROY_WITH_PARENT */
 
173
                                  GTK_MESSAGE_INFO,
 
174
                                  GTK_BUTTONS_CLOSE,
 
175
                                  message);
 
176
 
 
177
    gtk_window_set_title(GTK_WINDOW(dialog), _("Sensors Plugin"));
 
178
 
 
179
    checkbox = gtk_check_button_new_with_mnemonic (checkboxtext);
 
180
 
 
181
    gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), checkbox, FALSE, FALSE, 0);
 
182
    gtk_widget_show(checkbox);
 
183
 
 
184
    gtk_dialog_run(GTK_DIALOG(dialog));
 
185
 
 
186
    is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbox));
 
187
 
 
188
    gtk_widget_destroy (dialog);
 
189
 
 
190
    TRACE ("leaves quick_message");
 
191
 
 
192
    return is_active;
 
193
}
 
194
#endif
 
195
 
 
196
 
 
197
void quick_message (gchar *message)
 
198
{
 
199
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
200
    quick_message_notify (message);
 
201
#else
 
202
    quick_message_dialog (message);
 
203
#endif
 
204
}
 
205
 
 
206
 
 
207
#ifdef HAVE_NETCAT
 
208
 
 
209
void
 
210
read_disks_netcat (t_chip *chip)
 
211
{
 
212
    char reply[REPLY_MAX_SIZE], *tmp, *tmp2, *tmp3;
 
213
    size_t result;
 
214
 
 
215
    t_chipfeature *cf;
 
216
 
 
217
    result = get_hddtemp_d_str(reply, REPLY_MAX_SIZE);
 
218
    DBG ("reply=%s\n", reply);
 
219
 
 
220
    tmp = str_split (reply, DOUBLE_DELIMITER);
 
221
    do {
 
222
        //g_printf ("Found token: %s\n", tmp);
 
223
        cf = g_new0(t_chipfeature, 1);
 
224
 
 
225
        tmp2 = g_strdup (tmp);
 
226
        tmp3 = strtok (tmp2, SINGLE_DELIMITER);
 
227
        cf->devicename = g_strdup(tmp3);
 
228
        tmp3 = strtok (NULL, SINGLE_DELIMITER);
 
229
        cf->name = g_strdup(tmp3);
 
230
 
 
231
        g_ptr_array_add(chip->chip_features, cf);
 
232
        chip->num_features++;
 
233
 
 
234
        g_free (tmp2);
 
235
    }
 
236
    while ( (tmp = str_split(NULL, DOUBLE_DELIMITER)) );
 
237
 
 
238
//    g_free (stdoutput);
 
239
}
 
240
 
 
241
#else
 
242
void
 
243
read_disks_fallback (t_chip *chip)
 
244
{
 
245
    GError *error;
 
246
    GDir *gdir;
 
247
    t_chipfeature *chipfeature;
 
248
    const gchar* dirname;
 
249
 
 
250
    TRACE ("enters read_disks_fallback");
 
251
 
 
252
    /* read from /proc/ide */
 
253
    error = NULL;
 
254
    gdir = g_dir_open ("/proc/ide/", 0, &error);
 
255
 
 
256
    while ( (dirname = g_dir_read_name (gdir))!=NULL ) {
 
257
        if ( strncmp (dirname, "hd", 2)==0 || strncmp (dirname, "sd", 2)==0) {
 
258
            /* TODO: look, if /dev/dirname exists? */
 
259
            chipfeature = g_new0 (t_chipfeature, 1);
 
260
            chipfeature->devicename = g_strconcat ("/dev/", dirname, NULL);
 
261
            chipfeature->name = g_strdup(chipfeature->devicename);
 
262
            g_ptr_array_add (chip->chip_features, chipfeature);
 
263
            chip->num_features++;
 
264
        }
 
265
    }
 
266
 
 
267
    g_dir_close (gdir);
 
268
 
 
269
    /* FIXME: read SCSI info from where? SATA?  */
 
270
 
 
271
    TRACE ("leaves read_disks_fallback");
 
272
}
 
273
 
 
274
 
 
275
void
 
276
read_disks_linux26 (t_chip *chip)
 
277
{
 
278
    GDir *gdir;
 
279
    t_chipfeature *chipfeature;
 
280
    const gchar* dirname;
 
281
 
 
282
    TRACE ("enters read_disks_linux26");
 
283
 
 
284
    /* read from /sys/block */
 
285
    gdir = g_dir_open ("/sys/block/", 0, NULL);
 
286
    while ( (dirname = g_dir_read_name (gdir))!=NULL ) {
 
287
        /* if ( strncmp (dirname, "ram", 3)!=0 &&
 
288
             strncmp (dirname, "loop", 4)!=0 &&
 
289
             strncmp (dirname, "md", 2)!=0 &&
 
290
             strncmp (dirname, "fd", 2)!=0 &&
 
291
             strncmp (dirname, "mmc", 3)!=0 &&
 
292
             strncmp (dirname, "dm-", 3)!=0 ) { */
 
293
            if ( strncmp (dirname, "hd", 2)==0 ||
 
294
                            strncmp (dirname, "sd", 2)==0 ) {
 
295
            /* TODO: look, if /dev/dirname exists? */
 
296
            chipfeature = g_new0 (t_chipfeature, 1);
 
297
            chipfeature->devicename = g_strconcat ("/dev/", dirname, NULL); /* /proc/ide/hda/model ?? */
 
298
            chipfeature->name = g_strdup(chipfeature->devicename);
 
299
            g_ptr_array_add (chip->chip_features, chipfeature);
 
300
            chip->num_features++;
 
301
        }
 
302
    }
 
303
 
 
304
    g_dir_close (gdir);
 
305
 
 
306
    TRACE ("leaves read_disks_linux26");
 
307
}
 
308
#endif
 
309
 
 
310
void
 
311
remove_unmonitored_drives (t_chip *chip, gboolean *suppressmessage)
 
312
{
 
313
    int i, result;
 
314
    t_chipfeature *chipfeature;
 
315
 
 
316
    TRACE ("enters remove_unmonitored_drives");
 
317
 
 
318
    for (i=0; i<chip->num_features; i++)
 
319
    {
 
320
        chipfeature = g_ptr_array_index (chip->chip_features, i);
 
321
        result = get_hddtemp_value (chipfeature->devicename, suppressmessage);
 
322
        if (result == 0.0)
 
323
        {
 
324
            DBG ("removing single disk");
 
325
            free_chipfeature ( (gpointer) chipfeature, NULL);
 
326
            g_ptr_array_remove_index (chip->chip_features, i);
 
327
            i--;
 
328
            chip->num_features--;
 
329
        }
 
330
        else if (result == ZERO_KELVIN)
 
331
        {
 
332
            for (i=0; i < chip->num_features; i++) {
 
333
                DBG ("remove %d\n", i);
 
334
                chipfeature = g_ptr_array_index (chip->chip_features, i);
 
335
                free_chipfeature ( (gpointer) chipfeature, NULL);
 
336
            }
 
337
            g_ptr_array_free (chip->chip_features, TRUE);
 
338
            // chip->chip_features = g_ptr_array_new();
 
339
            chip->num_features=0;
 
340
            DBG ("Returning because of bad hddtemp.\n");
 
341
            return;
 
342
        }
 
343
    }
 
344
 
 
345
    TRACE ("leaves remove_unmonitored_drives");
 
346
}
 
347
 
 
348
 
 
349
void
 
350
populate_detected_drives (t_chip *chip)
 
351
{
 
352
    int diskIndex;
 
353
    /* double value; */
 
354
    t_chipfeature *chipfeature;
 
355
 
 
356
    TRACE ("enters populate_detected_drives");
 
357
 
 
358
    chip->sensorId = g_strdup(_("Hard disks"));
 
359
 
 
360
    for (diskIndex=0; diskIndex < chip->num_features; diskIndex++)
 
361
    {
 
362
       chipfeature = g_ptr_array_index (chip->chip_features, diskIndex);
 
363
       g_assert (chipfeature!=NULL);
 
364
 
 
365
       chipfeature->address = diskIndex;
 
366
 
 
367
       /* chipfeature->name = g_strdup(chipfeature->devicename); */
 
368
 
 
369
       chipfeature->color = g_strdup("#B000B0");
 
370
       chipfeature->valid = TRUE;
 
371
       chipfeature->formatted_value = g_strdup ("0.0"); /* _printf("%+5.1f", 0.0); */
 
372
       chipfeature->raw_value = 0.0;
 
373
 
 
374
       chipfeature->class = TEMPERATURE;
 
375
       chipfeature->min_value = 10.0;
 
376
       chipfeature->max_value = 50.0;
 
377
 
 
378
       chipfeature->show = FALSE;
 
379
    }
 
380
 
 
381
    TRACE ("leaves populate_detected_drives");
 
382
}
 
383
 
 
384
 
 
385
int
 
386
initialize_hddtemp (GPtrArray *chips, gboolean *suppressmessage)
 
387
{
 
388
    int generation, major, result, retval;
 
389
    struct utsname *p_uname;
 
390
    t_chip *chip;
 
391
 
 
392
    g_assert (chips!=NULL);
 
393
 
 
394
    TRACE ("enters initialize_hddtemp");
 
395
 
 
396
    chip = g_new0 (t_chip, 1);
 
397
 
 
398
/*    chip->chip_name = (const sensors_chip_name *)
 
399
            ( _("Hard disks"), 0, 0, _("Hard disks") ); */
 
400
 
 
401
    chip->chip_features = g_ptr_array_new ();
 
402
    chip->num_features = 0;
 
403
    chip->description = g_strdup(_("S.M.A.R.T. harddisk temperatures"));
 
404
    chip->name = g_strdup(_("Hard disks"));
 
405
    chip->sensorId = g_strdup("Hard disks");
 
406
    chip->type = HDD;
 
407
 
 
408
    p_uname = (struct utsname *) malloc (sizeof(struct utsname));
 
409
    result =  uname (p_uname);
 
410
    if (result!=0) {
 
411
        g_free(p_uname);
 
412
        return -1;
 
413
    }
 
414
 
 
415
    generation = atoi ( p_uname->release ); /* this might cause trouble on */
 
416
    major = atoi ( p_uname->release+2 );      /* other systems than Linux! */
 
417
                /* actually, wanted to use build time configuration therefore */
 
418
 
 
419
    /* Note: This is actually supposed to be carried out by ifdef HAVE_LINUX
 
420
     and major/minor number stuff from compile time*/
 
421
#ifdef HAVE_NETCAT
 
422
    read_disks_netcat (chip);
 
423
#else
 
424
    if (strcmp(p_uname->sysname, "Linux")==0 && major>=5)
 
425
        read_disks_linux26 (chip);
 
426
    else
 
427
        read_disks_fallback (chip); /* hopefully, that's a safe variant */
 
428
#endif
 
429
 
 
430
    g_free(p_uname);
 
431
 
 
432
    remove_unmonitored_drives (chip, suppressmessage);
 
433
    DBG  ("numfeatures=%d\n", chip->num_features);
 
434
    if ( chip->num_features>0 ) {  /* if (1) */
 
435
 
 
436
        populate_detected_drives (chip);
 
437
        g_ptr_array_add (chips, chip);
 
438
        retval = 2;
 
439
    }
 
440
    else {
 
441
        retval = 0;
 
442
    }
 
443
 
 
444
    TRACE ("leaves initialize_hddtemp");
 
445
 
 
446
    return retval;
 
447
}
 
448
 
 
449
 
 
450
 
 
451
int 
 
452
get_hddtemp_d_str (char *buffer, size_t bufsize)
 
453
{
 
454
    int sock;
 
455
    struct sockaddr_in servername;
 
456
    struct hostent *hostinfo;
 
457
    int nbytes = 0, nchunk = 0;
 
458
 
 
459
    /* Create the socket. */
 
460
    sock = socket(PF_INET, SOCK_STREAM, 0);
 
461
    if (sock < 0) {
 
462
            return -1;
 
463
    }
 
464
 
 
465
    /* Connect to the server. */
 
466
    servername.sin_family = AF_INET;
 
467
    servername.sin_port = htons(HDDTEMP_PORT);
 
468
    hostinfo = gethostbyname("localhost");
 
469
    if (hostinfo == NULL) {
 
470
/*      fprintf (stderr, "Unknown host %s.\n", hostname);*/
 
471
            return -1;
 
472
    }
 
473
    servername.sin_addr = *(struct in_addr *) hostinfo->h_addr;
 
474
 
 
475
    if (connect (sock, (struct sockaddr *) &servername, sizeof (servername)) < 0) {
 
476
/*      perror ("connect (client)");*/
 
477
            return -1;
 
478
    }
 
479
 
 
480
    /* Read data from server. */
 
481
    for (;;) {
 
482
      nchunk = read(sock, buffer+nbytes, bufsize-nbytes-1);
 
483
      if (nchunk < 0) {
 
484
          /* Read error. */
 
485
    /*      perror ("read");*/
 
486
          close (sock);
 
487
          return -1;
 
488
      } else if (nchunk == 0) {
 
489
          /* End-of-file. */
 
490
          break;
 
491
      } else {
 
492
          /* Data read. */
 
493
          nbytes += nchunk;
 
494
      }
 
495
    }
 
496
 
 
497
    buffer[nbytes] = 0;
 
498
    close (sock);
 
499
    return nbytes;
 
500
}
 
501
 
 
502
 
 
503
double
 
504
get_hddtemp_value (char* disk, gboolean *suppressmessage)
 
505
{
 
506
    gchar *standard_output=NULL, *standard_error=NULL;
 
507
    gchar *cmd_line=NULL, *msg_text=NULL;
 
508
 
 
509
#if !defined(HAVE_LIBNOTIFY4) && !defined(HAVE_LIBNOTIFY7)
 
510
    gchar *checktext = NULL;
 
511
#endif
 
512
    gint exit_status=0;
 
513
    double value;
 
514
    gboolean result=FALSE, nevershowagain;
 
515
    GError *error=NULL;
 
516
 
 
517
#ifdef HAVE_NETCAT
 
518
    gchar *tmp, *tmp2, *tmp3;
 
519
                char reply[REPLY_MAX_SIZE];
 
520
    size_t read_size;
 
521
#endif
 
522
 
 
523
    if (suppressmessage!=NULL)
 
524
        nevershowagain = *suppressmessage;
 
525
    else
 
526
        nevershowagain = FALSE;
 
527
 
 
528
    TRACE ("enters get_hddtemp_value for %s with suppress=%d", disk, nevershowagain); /* *suppressmessage); */
 
529
 
 
530
#ifdef HAVE_NETCAT
 
531
/*    exit_status = 1; // assume error by default
 
532
    cmd_line = g_strdup_printf ( "%s localhost %s", NETCAT_PATH, HDDTEMP_PORT);
 
533
    result = g_spawn_command_line_sync ( (const gchar*) cmd_line,
 
534
            &standard_output, &standard_error, &exit_status, NULL);
 
535
    error = g_new(GError, 1);
 
536
    error->message = g_strdup (_("No concrete error detected.\n"));
 
537
    if (exit_status==0)
 
538
*/
 
539
    read_size = get_hddtemp_d_str(reply, REPLY_MAX_SIZE);
 
540
 
 
541
    {
 
542
        tmp3 = "-255";
 
543
        tmp = str_split (reply, DOUBLE_DELIMITER);
 
544
        do {
 
545
            //g_printf ("Found token: %s for disk %s\n", tmp, disk);
 
546
            tmp2 = g_strdup (tmp);
 
547
            tmp3 = strtok (tmp2, SINGLE_DELIMITER); // device name
 
548
            if (strcmp(tmp3, disk)==0)
 
549
            {
 
550
                tmp3 = strtok(NULL, SINGLE_DELIMITER); // name
 
551
                tmp3 = strdup(strtok(NULL, SINGLE_DELIMITER)); // value
 
552
                // tmp3 = strtok(NULL, SINGLE_DELIMITER); // temperature unit
 
553
                exit_status = 0;
 
554
                g_free(error);
 
555
                error = NULL;
 
556
                g_free (tmp2);
 
557
                break;
 
558
            }
 
559
            g_free (tmp2);
 
560
        }
 
561
        while ( (tmp = str_split(NULL, DOUBLE_DELIMITER)) );
 
562
 
 
563
/*        g_free(standard_output);*/
 
564
        standard_output = tmp3;
 
565
 
 
566
    }
 
567
/*    else
 
568
    {
 
569
        error->message = g_strdup (standard_error);
 
570
    }*/
 
571
 
 
572
#else
 
573
    error = NULL;
 
574
    cmd_line = g_strdup_printf ( "%s -n -q %s", PATH_HDDTEMP, disk);
 
575
    result = g_spawn_command_line_sync ( (const gchar*) cmd_line,
 
576
            &standard_output, &standard_error, &exit_status, &error);
 
577
#endif
 
578
 
 
579
    msg_text = NULL; // wonder if this is still necessary
 
580
 
 
581
    DBG ("Exit code %d on %s with stdout of %s.\n", exit_status, disk, standard_output);
 
582
 
 
583
    /* filter those with no sensors out */
 
584
    if (exit_status==0 && strncmp(disk, "/dev/fd", 6)==0) { /* is returned for floppy disks */
 
585
        DBG("exit_status==0 && strncmp(disk, \"/dev/fd\", 6)==0");
 
586
        value = 0.0;
 
587
    }
 
588
    else if ((exit_status==256 || (standard_error && strlen(standard_error)>0))
 
589
            && access (PATH_HDDTEMP, X_OK)==0) /* || strlen(standard_error)>0) */
 
590
    {
 
591
        /* note that this check does only work for some versions of hddtemp. */
 
592
        if (!nevershowagain) {
 
593
            msg_text = g_strdup_printf(_("\"hddtemp\" was not executed correctly, "
 
594
                            "although it is executable. This is most probably due "
 
595
                            "to the disks requiring root privileges to read their "
 
596
                            "temperatures, and \"hddtemp\" not being setuid root."
 
597
                            "\n\n"
 
598
                            "An easy but dirty solution is to run \"chmod u+s %s"
 
599
                            "\" as root user and restart this plugin "
 
600
                            "or its panel.\n\n"
 
601
                            "Calling \"%s\" gave the following error:\n%s\nwith a return value of %d.\n"),
 
602
                            PATH_HDDTEMP, cmd_line, standard_error, exit_status);
 
603
 
 
604
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
605
            //msg_text = g_strconcat(msg_text, _("\nYou can disable these notifications in the settings dialog.\n");
 
606
            quick_message_notify (msg_text);
 
607
            nevershowagain = FALSE;
 
608
#else
 
609
            checktext = g_strdup(_("Suppress this message in future"));
 
610
            nevershowagain = quick_message_with_checkbox(msg_text, checktext);
 
611
#endif
 
612
 
 
613
            if (suppressmessage!=NULL)
 
614
                *suppressmessage = nevershowagain;
 
615
        }
 
616
        else {
 
617
            DBG  ("Suppressing dialog with exit_code=256 or output on standard_error");
 
618
        }
 
619
 
 
620
        value = ZERO_KELVIN;
 
621
    }
 
622
    /* else if (strlen(standard_error)>0) {
 
623
        msg_text = g_strdup_printf (_("An error occurred when executing"
 
624
                                      " \"%s\":\n%s"), cmd_line, standard_error);
 
625
        quick_message (msg_text);
 
626
        value = ZERO_KELVIN;
 
627
    } */
 
628
 
 
629
    else if (error && (!result || exit_status!=0))
 
630
    {
 
631
         DBG  ("error %s\n", error->message);
 
632
        if (!nevershowagain) {
 
633
            msg_text = g_strdup_printf (_("An error occurred when executing"
 
634
                                      " \"%s\":\n%s"), cmd_line, error->message);
 
635
#if defined(HAVE_LIBNOTIFY4) || defined(HAVE_LIBNOTIFY7)
 
636
            quick_message_notify (msg_text);
 
637
            nevershowagain = FALSE;
 
638
#else
 
639
            checktext = g_strdup(_("Suppress this message in future"));
 
640
            nevershowagain = quick_message_with_checkbox (msg_text, checktext);
 
641
#endif
 
642
 
 
643
             if (suppressmessage!=NULL)
 
644
                *suppressmessage = nevershowagain;
 
645
        }
 
646
        else {
 
647
            DBG  ("Suppressing dialog because of error in g_spawn_cl");
 
648
        }
 
649
        value = 0.0;
 
650
    }
 
651
    else if (standard_output && strlen(standard_output) > 0)
 
652
    {
 
653
        DBG("got the only useful return value of 0 and value of %s.\n", standard_output);
 
654
        /* hddtemp does not return floating values, but only integer ones.
 
655
          So have an easier life with atoi.
 
656
          FIXME: Use strtod() instead?*/
 
657
        value = (double) (atoi ( (const char*) standard_output) );
 
658
    }
 
659
    else {
 
660
        DBG("No condition applied.");
 
661
        value = 0.0;
 
662
    }
 
663
 
 
664
    g_free (cmd_line);
 
665
    g_free (standard_output);
 
666
    g_free (standard_error);
 
667
    g_free (msg_text);
 
668
#if !defined(HAVE_LIBNOTIFY4) && !defined(HAVE_LIBNOTIFY7)
 
669
    g_free (checktext);
 
670
#endif
 
671
 
 
672
    if (error) 
 
673
      g_error_free(error);
 
674
 
 
675
    TRACE ("leaves get_hddtemp_value");
 
676
 
 
677
    return value;
 
678
}
 
679
 
 
680
 
 
681
void
 
682
refresh_hddtemp (gpointer chip_feature, gpointer data)
 
683
{
 
684
    t_chipfeature *cf;
 
685
    double value;
 
686
    t_sensors *sensors;
 
687
    gboolean *suppress = NULL;
 
688
 
 
689
    g_assert (chip_feature!=NULL);
 
690
 
 
691
    TRACE ("enters refresh_hddtemp");
 
692
 
 
693
    if (data != NULL)
 
694
    {
 
695
        sensors = (t_sensors *) data;
 
696
        suppress = &(sensors->suppressmessage);
 
697
    }
 
698
 
 
699
    cf = (t_chipfeature *) chip_feature;
 
700
 
 
701
    value = get_hddtemp_value (cf->devicename, suppress);
 
702
 
 
703
    /* actually, that's done in the gui part */
 
704
    g_free (cf->formatted_value);
 
705
    /*  if (scale == FAHRENHEIT) {
 
706
        cf->formatted_value = g_strdup_printf(_("%.1f °F"), (float) (value * 9/5 + 32) );
 
707
    } else { // Celsius  */
 
708
        cf->formatted_value = g_strdup_printf(_("%.1f °C"), value);
 
709
    /* } */
 
710
    cf->raw_value = value;
 
711
 
 
712
    TRACE ("leaves refresh_hddtemp");
 
713
}
 
714