-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patht.cpp
350 lines (284 loc) · 12.4 KB
/
t.cpp
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#include <string>
#include <vector>
#include <iostream>
// #include <stdio.h> // itoa
#include <fstream>
#include <sys/stat.h> // provide stat functionality for directory checking
#include <string.h> // provide c string capabilities
#include <unistd.h> // provide functionality for UNIX calls
#include <stdlib.h> // malloc, calloc, free
#include <typeinfo>
using namespace std;
#define MAX_PATH 1000 // maximum file path is probably not more than 1000 chars
#define USER_DIR "/files" // directory (relative to CWD) where data on all users for texty will be stored
#define ALL_USERS_FILE "/all_users.txt" // corresponds to file with every user's info and index number
#define USER_DATA_FILENAME "all_users.txt"
#define MAX_INDEX_BYTES 10 // maximum number of user indexes that can be used at creation of files: 10 bytes = 999999999 possible indexes for a cstring
#define MAX_USER_INFO_BYTES 118 // maximum number of bytes each line in all_users.txt will be for each user including: user's data, commas, and '\n' character
#define UN_BYTES 17 // maximum number of characters in username based on value limited in PHP file
#define EMAIL_BYTES 41 // maximum number of characters in email based on value limited in PHP file
#define PW_BYTES 17 // maximum number of characters in password based on value limited in PHP file
#define FN_BYTES 21 // maximum number of characters in first name based on value limited in PHP file
#define LN_BYTES 21 // maximum number of characters in last name based on value limited in PHP file
#define GARBAGE_BYTES 70 // length of bytes to hold characters after username and email fields in file handling
#define CURRENT_DIR "~/Dropbox/Coding/PDC/texty_cpp/" // directory where C++ files and user file directory is stored
// 1. register, 2. log in, 3. deactivate
bool user_exists(fstream& fh, int check, const string& un, const string& email, const string& pw = "")
{
// skip the first of the line of the file because it does not contain user info
string first_line_garbage;
fh.clear(); fh.seekp(0, ios::beg); getline(fh, first_line_garbage);
// test_info is one line from the all_users.txt file
// test_info = un,email,index,pw,fn,ln
char* test_un = (char*) malloc(UN_BYTES);
char* test_email = (char*) malloc(EMAIL_BYTES);
char* test_pw = (char*) malloc(PW_BYTES);
char* garbage = (char*) malloc(MAX_USER_INFO_BYTES);
while (!fh.eof()) {
// Test username
fh.get(test_un, UN_BYTES, ','); // comma separated values, so ',' is the delim parameter
// ',' is the next character in the stream, so just get that
fh.get();
fh.get(test_email, EMAIL_BYTES, ','); // comma separated values, so ',' is the delim parameter
// ',' is the next character in the stream, so just get that
fh.get();
// garbage and .get() will get the index value of the user and the following ','
fh.get(garbage, GARBAGE_BYTES, ',');
fh.get();
fh.get(test_pw, PW_BYTES, ','); // comma separated values, so ',' is the delim parameter
// garbage and .get() will get the next ',' along with the rest of the user info that is not need for testing
fh.get(); //garbage, 2);
fh.getline(garbage, GARBAGE_BYTES);
// 1) test username or email, 2) test username and password, 3) test username, email, and password
switch (check)
{
case 1: // Register: both the username and email should be unique
if( (strcmp(test_un, un.c_str()) == 0) || (strcmp(test_email, email.c_str()) == 0) ) {
free(test_un); free(test_email); free(test_pw); free(garbage);
return true;
}
case 2: // Log in: both the username and password should match
if( (strcmp(test_un, un.c_str()) == 0) && (strcmp(test_pw, pw.c_str()) == 0) ) {
free(test_un); free(test_email); free(test_pw); free(garbage);
return true;
}
case 3: // Deactivate: the username, email, and password should match
if( (strcmp(test_un, un.c_str()) == 0) && (strcmp(test_email, email.c_str()) == 0) && (strcmp(test_pw, pw.c_str()) == 0) ) {
free(test_un); free(test_email); free(test_pw); free(garbage);
return true;
}
}
}
free(test_un); free(test_email); free(test_pw); free(garbage);
return false; // got to the end of the file so return false
}
/*
The file passed in will be the followees.txt or followers.txt file containing the user we want to remove;
The index corresponds to the index of the user we will be removing
*/
void remove_user_from_files(fstream& fh, ofstream& temp_file, const string& index)
{
string temp, temp_index;
while (!fh.eof()) {
getline(fh, temp);
for (size_t i = 0; i < temp.size(); ++i) {
if (temp[i] == ',')
break;
temp_index += temp[i];
}
// if the current line's index is not the user we are removing, add them to the new temp file
if (temp_index != index && temp != "") {
temp_file << temp;
temp_file << "\n";
}
temp_index.clear();
}
}
/*
Remove the user from all_users.txt
Remove the user from the followees.txt file of anyone in the user's followers.txt file
Remove the user from the followers.txt file of anyone in the user's followees.txt file
Delete the user's followees.txt, followers.txt, and texts.txt files and the user's directory
*/
void remove_user(fstream& fh, ofstream& temp_file, const string& un, const string& email, const string& pw, const char* my_cwd)
{
string user_index;
/* ---------------------------- REMOVING USER FROM all_users.txt --------------------------------- */
string temp, temp_username;
// place the first line of all_users.txt into the new temp file
fh.clear(); fh.seekp(0, ios::beg);
getline(fh, temp);
temp_file << temp; temp_file << "\n";
// add all lines of all_users.txt that don't match the specified username into the new temp file
while (!fh.eof()) {
getline(fh, temp);
size_t i;
for (i = 0; i < temp.size(); ++i) {
if (temp[i] == ',')
break;
temp_username += temp[i];
}
// if the current line's user is the not the user we are removing, add them to the new temp file
if (temp_username != un && temp != "") {
temp_file << temp;
temp_file << "\n";
} else if (temp_username == un) { // this is the user we are removing
// get user's index
// first we must parse through the next data value which is the email and i is already at the index of email's first char
for (++i; i < temp.size(); ++i) {
if (temp[i] == ',')
break;
}
// get user's index value until the next comma is hit
for (++i; i < temp.size(); ++i) {
if (temp[i] == ',')
break;
user_index += temp[i];
}
}
temp_username.clear();
}
fh.close();
/* ---------- REMOVING USER FROM OTHER PEOPLE'S followers.txt && followees.txt files ------------- */
// set up variables to change directories, assuming our CWD is where the "files" directory is located
char* files_cwd = (char*) malloc(MAX_PATH); // will hold directory of "/files"
char* user_dir_cwd = (char*) malloc(MAX_PATH); // will hold directory of "/files/X" where X is a number representing this user's directory
char* other_user_dir_cwd = (char*) malloc(MAX_PATH); // will hold directory of "/files/Y" where Y is a number representing another user's directory
char* temp_dir = (char*) malloc(MAX_PATH); // will hold directory of "/files/" as a way to use strcpy to reset other_user_dir_cwd for each new other user's index value
getcwd(files_cwd, MAX_PATH);
// Change the current directory to the user's directory who is being removed
getcwd(user_dir_cwd, MAX_PATH);
strcat(user_dir_cwd, "/");
strcat(user_dir_cwd, user_index.c_str());
getcwd(other_user_dir_cwd, MAX_PATH);
strcat(other_user_dir_cwd, "/");
getcwd(temp_dir, MAX_PATH);
strcat(temp_dir, "/");
chdir(user_dir_cwd);
// delete the user's texts.txt file
remove("texts.txt");
// for each other user in this user's followees.txt file, remove this user from the other user's followers.txt file
fstream followees_file("followees.txt");
string other_user_index;
while (!followees_file.eof()) {
getline(followees_file, temp);
if (temp != "") {
for (size_t i = 0; i < temp.size(); ++i) {
if (temp[i] == ',')
break;
other_user_index += temp[i];
}
// change to the directory to the other user's directory and open their followers.txt file
strcat(other_user_dir_cwd, other_user_index.c_str());
chdir(other_user_dir_cwd);
fstream other_followers_file("followers.txt");
ofstream other_followers_temp_file("temp.txt");
// remove the current user from the other user's followers.txt file
remove_user_from_files(other_followers_file, other_followers_temp_file, user_index);
// remove the old file with the user currently in it, and rename the new temp file to its name
remove("followers.txt");
rename("temp.txt", "followers.txt");
other_followers_file.close(); other_followers_temp_file.close();
other_user_index.clear();
// reset other_user_dir_cwd to be concatenated with the next other user index
strcpy(other_user_dir_cwd, temp_dir);
}
}
followees_file.close();
chdir(user_dir_cwd); // change directories back to the current user being removed to get his/her followers.txt file
fstream followers_file("followers.txt");
while (!followers_file.eof()) {
getline(followers_file, temp);
if (temp != "") {
for (size_t j = 0; j < temp.size(); ++j) {
if( temp[j] == ',')
break;
other_user_index += temp[j];
}
// change to the directory to the other user's directory and open their followers.txt file
strcat(other_user_dir_cwd, other_user_index.c_str());
chdir(other_user_dir_cwd);
fstream other_followees_file("followees.txt");
ofstream other_followees_temp_file("temp.txt");
// remove the current user from the other user's followers.txt file
remove_user_from_files(other_followees_file, other_followees_temp_file, user_index);
// remove the old file with the user currently in it, and rename the new temp file to its name
remove("followees.txt");
rename("temp.txt", "followees.txt");
other_followees_file.close(); other_followees_temp_file.close();
other_user_index.clear();
// reset other_user_dir_cwd to be concatenated with the next other user index
strcpy(other_user_dir_cwd, temp_dir);
}
}
followers_file.close();
chdir(user_dir_cwd);
remove("followees.txt");
remove("followers.txt");
chdir(my_cwd); // setting the working directory back to what it was before the remove_user function was called
rmdir(user_dir_cwd);
free(files_cwd); free(user_dir_cwd); free(other_user_dir_cwd); free(temp_dir);
}
int main()
{
chdir(CURRENT_DIR);
string un, email, pw, garbage;
un = "ld"; email = "ld@g"; pw = "bye";
char* my_cwd = (char*) malloc(MAX_PATH);
char* files_cwd = (char*) malloc(MAX_PATH);
getcwd(my_cwd, MAX_PATH);
getcwd(files_cwd, MAX_PATH);
strcat(files_cwd, USER_DIR);
chdir(files_cwd);
fstream fh(USER_DATA_FILENAME);
getline(fh, garbage); // first line is the index of the next user and commas
if (user_exists(fh, 3, un, email, pw)) {
ofstream temp_file("temp.txt");
remove_user(fh, temp_file, un, email, pw, files_cwd);
remove(USER_DATA_FILENAME);
rename("temp.txt", USER_DATA_FILENAME);
} else {
cout << "Data did not match user -- no deactivation" << endl;
}
chdir(my_cwd);
// place the first of the all_users.txt into the new temp file
// fstream fh("all_users.txt");
// getline(fh, garbage);
// if (user_exists(fh, 1, un, email))
// cout << "Test username/email already exists" << endl;
// else
// cout << "That username and password do not already exist, good job" << endl;
// fh.clear(); fh.seekp(0, ios::beg); getline(fh, garbage);
// if (user_exists(fh, 2, un, "", pw))
// cout << "Logged in" << endl;
// else
// cout << "Not logged in" << endl;
// fh.clear(); fh.seekp(0, ios::beg); getline(fh, garbage);
// if (user_exists(fh, 3, un, email,pw))
// cout << "Deactivated" << endl;
// else
// cout << "Not deactivated" << endl;
// // register - 1
// if (user_exists(fh, 1, un, email))
// cout << "That username/password already exists" << endl;
// else
// cout << "That username and password do already exist" << endl;
// fh.close();
// fstream fh2("all_users.txt");
// fh.clear();
// fh.seekp(0, ios::beg);
// getline(fh, garbage);
// // 2 - log in
// if (user_exists(fh2, 2, un, "null", pw))
// cout << "You're logged in" << endl;
// else
// cout << "Log in info incorrect" << endl;
// fh.close();
// fstream fh3("all_users.txt");
// getline(fh, garbage);
// // deactivate - 3
// if (user_exists(fh3, 3, un, email, pw))
// cout << "You're deactived" << endl;
// else
// cout << "No deactivation for you!" << endl;
}