#include <stdio.h>
#include <errno.h>
#include <linux/unistd.h>     
#include <linux/kernel.h>   
#include <time.h>
#include <utmp.h>

#define appname "d's uptime"
#define appversion "0.8"

#define ONEDAY  86400
#define ONEHOUR  3600
#define ONEMINUTE  60
#define LOADS_SCALE 65536.0

_syscall1(int, sysinfo, struct sysinfo *, info);

int getTime(void) {
    struct tm *tm_ptr;
    time_t the_time;

    (void) time(&the_time);
    tm_ptr = localtime(&the_time);

    printf(" %02d:%02d:%02d", tm_ptr->tm_hour, tm_ptr->tm_min, tm_ptr->tm_sec);
    return(0);
}

int getUptime(void) {
    struct sysinfo s_info;
    int error; 
    error = sysinfo(&s_info);

    int days; int hours; int minutes;
    long int upmind; long int upminh;
    long int uptimes;

    uptimes = s_info.uptime; // returned in seconds
    days = uptimes / ONEDAY;
    upmind = uptimes - (days * ONEDAY);
    hours = upmind / ONEHOUR;
    upminh = upmind - hours * ONEHOUR;
    minutes = upminh / ONEMINUTE;

    float av1, av2, av3;
    av1 = s_info.loads[0] / LOADS_SCALE;
    av2 = s_info.loads[1] / LOADS_SCALE;
    av3 = s_info.loads[2] / LOADS_SCALE;

    // This next block is stolen fron GNU uptime
    struct utmp *utmpstruct;
    int numuser = 0;
    setutent();
    while ((utmpstruct = getutent())) {
        if ((utmpstruct->ut_type == USER_PROCESS) &&
            (utmpstruct->ut_name[0] != '\0'))
            numuser++;
    }
    endutent();

    printf(" up %i day%s, %02i:%02i, %i user%s, load average: %2.2f, %2.2f, %2.2f\n",
            days, (days != 1) ? "s" : "", hours, minutes, numuser, (numuser != 1) ? "s" : "", av1, av2, av3);
    return(0);
}

int main(int argc, char *argv[]) {
    int opt;

    while ((opt = getopt(argc, argv, "V")) != -1) {
        switch(opt) {
           case 'V': printf("%s version %s\n", appname, appversion); exit(0); break;
           default : printf("usage: uptime [-V]\n\t-V    display version\n"); exit(1);
        }
    }
    getTime();
    getUptime();
    return(0);
}


syntax highlighted by Code2HTML, v. 0.9.1