aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
blob: ebfb9e6f178817fde92d9510a986f69cf35c5917 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

static char *
get_tty_name(void)
{ /* Returns the name of the tty connected to the file descriptor for
     `stdin'. */
  return ttyname(STDIN_FILENO);
}

static char *
get_filename(void)
{ /* Generate the filename to be used for the current tty. Uses both
     the user ID of the calling user and the name of the current tty
     to make it unique. */
  char *filename = malloc(sizeof(char) * 255);
  char *tty = get_tty_name();
  char *pch;

  while ((pch = strchr(tty, '/')))
    *pch = '_';

  sprintf(filename, "/tmp/baps1_%u_%s", getuid(), tty);

  return filename;
}

static time_t
load_previous_time(char *filename)
{ /* Loads the previously saved timestamp from FILENAME. This function
     assumes the file exists and is readable. */
  FILE *timefile = fopen(filename, "r");
  time_t prev;

  fscanf(timefile, "%ld", &prev);
  fclose(timefile);

  return prev;
}

static time_t
get_previous_time(char *filename)
{ /* Tries to get the previously saved timestamp from FILENAME, but if
     it can't read the file returns 0. */
  time_t prev;

  if (access(filename, R_OK) == 0) {
    prev = load_previous_time(filename);
  }
  else {
    prev = 0;
  }

  return prev;
}

static int
get_tty_number(void)
{ /* Gets the number of the current tty. It assumes that the number is
     an integer and consists of everything after the last `/' of the
     tty's name. */
  char *tty = get_tty_name();
  char *num = strrchr(tty, '/') + 1;

  return atoi(num);
}

static char
get_tty_type(void)
{ /* Gets the type of the tty represented by the first letter of the
     type, either `t' or `p'. Assumes that the type comes immediately
     after `/dev/'. */
  char *tty = get_tty_name();

  strtok(tty, "/");             /* dev */

  return strtok(NULL, "/")[0];
}

static int
save_current_time(char *filename)
{ /* Save the timestamp for this moment to FILENAME. Returns `1' when
     succesful, `0' when the file couldn't be opened. */
  FILE *timefile = fopen(filename, "w");
  time_t now;

  if (!timefile)
    return 0;

  time(&now);
  fprintf(timefile, "%ld", now);
  fclose(timefile);

  return 1;
}

static void
print_time_since(time_t lasttime)
{ /* Print the hours, minutes and seconds that have passed since
     LASTTIME to `stdout'. */
  double h, m, s;
  time_t now;

  time(&now);
  s = difftime(now, lasttime);

  if (s >= 60.0) {
    m = floor(s / 60.0);
    s -= m * 60;

    if (m >= 60.0) {
      h = floor(m / 60.0);
      m -= h * 60;

      printf("%.0lfh", h);
    }

    printf("%.0lfm", m);
  }

  printf("%.0lfs", s);
}

int
main()
{ /* This program prints a single letter represetation of the type and
     number of the current tty and the time elapsed since the last
     call to this program on this tty, or `new'. It then saves a
     timestamp to a file in /tmp/ so that it can check the elapsed
     time during its next run. */
  char *filename = get_filename();
  time_t lasttime = get_previous_time(filename);

  printf("%c%d:", get_tty_type(), get_tty_number());

  if (lasttime > 0) {
    print_time_since(lasttime);
  }
  else {
    puts("new");
  }

  save_current_time(filename);
  free(filename);

  return EXIT_SUCCESS;
}