1 /*
2 ** Copyright (c) 2010 Michael Dvorkin
3 **
4 ** This program is free software; you can redistribute it and/or
5 ** modify it under the terms of the Simplified BSD License (also
6 ** known as the "2-Clause License" or "FreeBSD License".)
7 **
8 ** This program is distributed in the hope that it will be useful,
9 ** but without any warranty; without even the implied warranty of
10 ** merchantability or fitness for a particular purpose.
11 */
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <unistd.h>
17 #include <pwd.h>
18 #include <sys/types.h>
19 #include "pit.h"
20
str2str(char * str)21 char *str2str(char *str) {
22 return strcpy(malloc(strlen(str) + 1), str); /* Cheap strdup() */
23 }
24
mem2str(char * mem,int len)25 char *mem2str(char *mem, int len) {
26 char *str = malloc(len + 1);
27 memcpy(str, mem, len);
28 str[len] = '\0';
29
30 return str;
31 }
32
is_zero(char * mem,int len)33 bool is_zero(char *mem, int len) {
34 char *pch = mem;
35
36 while(pch - mem < len) {
37 if (*pch++) return FALSE;
38 }
39 return TRUE;
40 }
41
stristr(char * haystack,char * needle)42 char *stristr(char *haystack, char *needle)
43 {
44 char *start, *pn, *ps;
45
46 for (start = haystack; *start; start++) {
47 for (; (*start && (toupper(*start) != toupper(*needle))); start++) ;
48 if (!*start) return NULL;
49
50 ps = start; pn = needle;
51 while (toupper(*ps++) == toupper(*pn++)) {
52 if (!*pn) return start;
53 }
54 }
55 return NULL;
56 }
57
printa(char * msg[])58 void printa(char *msg[]) {
59 while(*msg) puts(*msg++);
60 }
61
current_user()62 char *current_user() {
63 static char *username = NULL;
64
65 if (!username) {
66 struct passwd *pws = getpwuid(geteuid());
67 if (!pws) {
68 perish("no username?!");
69 } else {
70 username = pws->pw_name;
71 }
72 }
73 return username;
74 }
75
home_dir(char * username,int len)76 char *home_dir(char *username, int len) {
77 char *str = mem2str(username, len);
78 struct passwd *pw = getpwnam(str);
79 free(str);
80
81 return (pw ? pw->pw_dir : NULL);
82 }
83
expand_path(char * path,char * expanded)84 char *expand_path(char *path, char *expanded) {
85 if (!path || *path != '~') {
86 return path;
87 } else {
88 char *next = path + 1;
89 if (*next == '/') { /* Path without the username, i.e. ~/file */
90 strcpy(expanded, getenv("HOME"));
91 strcat(expanded, next);
92 } else { /* Path with the username, i.e. ~username/file */
93 char *slash = strchr(next, '/');
94 if (!slash) {
95 slash = next + strlen(next);
96 }
97 char *home = home_dir(next, slash - next);
98 if (!home) { /* Ex. non-existent username. */
99 perish(path);
100 } else {
101 strcpy(expanded, home);
102 strcat(expanded, slash);
103 }
104 }
105 }
106
107 return expanded;
108 }
109
format_date(time_t date)110 char *format_date(time_t date)
111 {
112 static char str[32];
113 struct tm *ptm;
114
115 ptm = localtime(&date);
116 if (!ptm->tm_hour && !ptm->tm_min && !ptm->tm_sec) {
117 strftime(str, sizeof(str), "%b %d, %Y", ptm);
118 } else {
119 strftime(str, sizeof(str), "%b %d, %Y %H:%M", ptm);
120 }
121 return str;
122 }
123
format_time(time_t time)124 char *format_time(time_t time)
125 {
126 static char str[10];
127 int hh = time / 3600;
128 int mm = (time - hh * 3600) / 60;
129
130 sprintf(str, "%d:%02d", hh, mm);
131 return str;
132 }
133
format_timestamp(time_t timestamp)134 char *format_timestamp(time_t timestamp)
135 {
136 static char str[32];
137 struct tm *ptm = localtime(×tamp);
138
139 strftime(str, sizeof(str), "%b %d, %Y at %H:%M", ptm);
140
141 return str;
142 }
143
inline_replace(char * this,char * old,char * new)144 char *inline_replace(char *this, char *old, char *new)
145 {
146 char *start = this;
147 char *next = this;
148 int new_length = strlen(new);
149 int old_length = strlen(old);
150
151 if (this && old && new && (old_length > 0) && (old_length >= new_length)) {
152 while (*this) {
153 if (strncmp(this, old, old_length)) {
154 *next++ = *this++; /* Not a start of old thising, copy character unchanged. */
155 } else {
156 strncpy(next, new, new_length); /* Found the old string, replace it with the new one. */
157 next += new_length; /* Adjust pointers to move beyond replaced string. */
158 this += old_length;
159 }
160 }
161 *next = '\0';
162 }
163 return start;
164 }
165
166 #ifdef TEST
main(int argc,char * argv[])167 int main(int argc, char *argv[]) {
168 printf("your username: %s\n", current_user());
169 printf("your (cached) username: %s\n", current_user());
170 return 1;
171 }
172 #endif
173