-
Notifications
You must be signed in to change notification settings - Fork 0
/
changer.c
146 lines (122 loc) · 3.41 KB
/
changer.c
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
#define _DEFAULT_SOURCE
#include<errno.h>
#include<limits.h>
#include<linux/limits.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/fcntl.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<time.h>
#include<unistd.h>
#define IOCONTROL_CMD _IOW(0xCD, 0x19, char*) // Allows Linux system call to access underlying device parameters of files
struct path_data
{
char* path;
size_t size;
struct timespec time;
char* command;
};
int main(int argc, char **argv)
{
int file = open("/dev/timem", O_RDWR); // Open driver file
// Check for error from opening file
if(file < 0)
{
fprintf(stderr, "Could not open driver's device\n");
return 1;
}
/*
Four command line args:
1. Program path (i.e. the path to ./changer)
2. Path of item we wish to modify
3. What trait to modify (LM, DA, DC)
4. Time
*/
// Check for correct number of arguments
if(argc != 4)
{
fprintf(stderr, "Invalid number of arguments! \n");
goto failure; // Closes file and returns 1
}
// Begin parsing arguments
char validPath[PATH_MAX];
struct tm tinfo;
struct path_data data;
// Check that the file path is valid
if(realpath(argv[1], validPath) != validPath)
{
fprintf(stderr, "Invalid path: '%s'\n", argv[1]);
goto failure; // Closes file and returns 1
}
data.path = validPath;
data.size = strlen(validPath) + 1;
// Get the third parameter and transfer its data to a time struct
sscanf(argv[3], "%u.%u.%u-%u:%u:%u:%ld", &tinfo.tm_mday, &tinfo.tm_mon,
&tinfo.tm_year, &tinfo.tm_hour, &tinfo.tm_min, &tinfo.tm_sec,
&data.time.tv_nsec);
tinfo.tm_year -= 1900; //relative time
tinfo.tm_mon -= 1;
data.time.tv_sec = mktime(&tinfo);
if(data.time.tv_sec < 0 || data.time.tv_nsec < 0 || data.time.tv_nsec >= 100000000L){
fprintf(stderr, "Invalid time: '%s'\n", argv[3]);
goto failure;
}
if(strcmp(argv[2], "LM") == 0)
{
data.command = "LM";
printf("Processing...\n");
/*
ioctl() - System call that manipulates the underlying
device parameters of files.
Check that the system call modified the file time
*/
if(ioctl(file, IOCONTROL_CMD, &data) < 0)
{
fprintf(stderr, "Failed to change time of '%s': %s\n", argv[1], strerror(errno));
}
printf("Changed 'Last Modified' time of '%s' to %s\n", argv[1], asctime(&tinfo));
}
else if (strcmp(argv[2], "DA") == 0)
{
data.command = "DA";
printf("Processing...\n");
/*
ioctl() - System call that manipulates the underlying
device parameters of files.
Check that the system call modified the file time
*/
if(ioctl(file, IOCONTROL_CMD, &data) < 0)
{
fprintf(stderr, "Failed to change time of '%s': %s\n", argv[1], strerror(errno));
}
printf("Changed 'Date Accessed' time of '%s' to %s\n", argv[1], asctime(&tinfo));
}
else if (strcmp(argv[2], "DC") == 0)
{
data.command = "DC";
printf("Processing...\n");
/*
ioctl() - System call that manipulates the underlying
device parameters of files.
Check that the system call modified the file time
*/
if(ioctl(file, IOCONTROL_CMD, &data) < 0)
{
fprintf(stderr, "Failed to change time of '%s': %s\n", argv[1], strerror(errno));
}
printf("Changed 'Date Changed' time of '%s' to %s\n", argv[1], asctime(&tinfo));
}
else
{
fprintf(stderr,"%s is not a valid operation!\nPlease enter LM or DA or DC.\n", argv[2]);
goto failure;
}
close(file);
return 0;
// Close file and return error if failure
failure:
close(file);
return 1;
}