#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <conio.h>
struct DATA
{
int number=0;
char surname[12], name[10], patronymic[15];
int BirthDate, BirthMonth, BirthYear;
char addresSTREET[16];
int addresHOME;
int mobileNUMBER;
};
int ENTER_CHOICE(void);
void NEW_DATA(FILE*);
void VIEW_DATA(FILE*);
void ENTER_DATA(struct DATA*);
void UPDATE_RECORD(FILE*);
void ADD_RECORD(FILE*);
void DELETE_RECORD(FILE*);
void SEARCH_RECORD(FILE*);
void SORT_DATA(FILE*);
int CHECK_INTEGER(int,int);
int main()
{
//Русификация консоли ввода/вывода
SetConsoleCP(1251); //установка кодовой страницы win-cp 1251 в поток ввода
SetConsoleOutputCP(1251); //установка кодовой страницы win-cp 1251 в поток вывода
FILE* cfPtr;
char fname[20];
int choice;
int access_mode;
printf("Продолжить работу в старом файле?\n" "(1)-Да (0)-Нет, я хочу создать новый\n->");
scanf("%d", &access_mode
);
printf("Введите название файла (name.txt)\n-> "); //while (getchar() != '\n');
//fgets(fname, sizeof(fname), stdin);
do {
if (access_mode == 1) {
if ((cfPtr
= fopen(fname
, "r+")) == NULL
) { printf("File could not be opened.\n"); return 0;
}
}
else {
if ((cfPtr
= fopen(fname
, "w+")) == NULL
) { printf("File could not be opened.\n"); return 0;
}
access_mode = 1;
}
choice = ENTER_CHOICE();
switch (choice)
{
case 0: return 0;
case 1:
NEW_DATA(cfPtr);
break;
case 2:
VIEW_DATA(cfPtr);
break;
case 3:
UPDATE_RECORD(cfPtr);
break;
case 4:
ADD_RECORD(cfPtr);
break;
case 5:
DELETE_RECORD(cfPtr);
break;
case 6:
SEARCH_RECORD(cfPtr);
break;
case 7:
SORT_DATA(cfPtr);
break;
}
if (choice != 0)
} while (choice!=0);
}
int ENTER_CHOICE(void)
{
int choice;
char buf[100]; // строка для считывания введённых данных
printf("Выберите, что вам нужно сделать\n" "0 -> Выход из программы\n"
"1 -> Создание новой базы данных\n"
"2 -> Просмотр существующей базы данных\n"
"3 -> Редактирование базы данных\n"
"4 -> Дополнение базы данных новыми записями\n"
"5 -> Удаление записей из базы данных\n"
"6 -> Поиск в базе данных\n"
"7 -> Сортировка пользователей по фамилии\n-> ");
/*scanf("%s", buf); */
fgets(buf
, sizeof(buf
), stdin
);// считываем строку // пока ввод некорректен, сообщаем об этом и просим повторить его
while (sscanf(buf
, "%d", &choice
) != 1 || choice
< 0 || choice
> 7) {
printf("Неверно введено значение. Попробуйте снова ->"); // выводим сообщение об ошибке /*scanf("%s", buf);*/
fgets(buf
, sizeof(buf
), stdin
);// считываем строку повторно }
return choice;
}
void NEW_DATA(FILE* fPtr)
{
int ans = 1;
struct DATA notebook;
do{
notebook.number++;
ENTER_DATA(¬ebook);
fseek(fPtr
, notebook.
number * sizeof(struct DATA
), SEEK_SET
); fwrite(¬ebook
, sizeof(struct DATA
), 1, fPtr
); printf("Введите (1) - чтобы добавить еще (0) - закончить\n-> "); } while (ans != 0);
}
void VIEW_DATA(FILE* readPtr)
{
DATA buf;
printf("%-2s| %-12s | %-10s | %-15s | %-13s | %-16s | %-11s |\n", "№","Фамилия","Имя","Отчество","Дата Рождения","Адрес","моб.телефон");
fseek(readPtr
, 0 * sizeof(struct DATA
), SEEK_SET
); while (fread(&buf
, sizeof(buf
), 1, readPtr
)) {
if(buf.number!=0)
printf("%-2d| %-12s | %-10s | %-15s | %02d.%02d.%04d | %-12s,%-3d | %-11d |\n", buf.number, buf.surname, buf.name, buf.patronymic,
buf.BirthDate, buf.BirthMonth, buf.BirthYear,
buf.addresSTREET, buf.addresHOME, buf.mobileNUMBER);
}
}
int CHECK_INTEGER(int a, int b)
{
char buf[256];
int user_number;
fgets(buf
, sizeof(buf
), stdin
); while (sscanf(buf
, "%d", &user_number
) != 1 || user_number
< a
|| user_number
> b
) {
printf("Ошибка ввода. Попробуйте еще раз\n-> "); fgets(buf
, sizeof(buf
), stdin
); }
return user_number;
}
void ENTER_DATA(struct DATA* notebook)
{
printf("Введите фамилию -> "); fgets(notebook
->surname
, sizeof(notebook
->surname
), stdin
); notebook
->surname
[strcspn(notebook
->surname
, "\n")] = 0;
fgets(notebook
->name
, sizeof(notebook
->name
), stdin
); notebook
->name
[strcspn(notebook
->name
, "\n")] = 0;
printf("Введите отчество -> "); fgets(notebook
->patronymic
, sizeof(notebook
->patronymic
), stdin
); notebook
->patronymic
[strcspn(notebook
->patronymic
, "\n")] = 0;
printf("Введите дату рождения:\nДень -> "); notebook->BirthDate=CHECK_INTEGER(1, 31);
notebook->BirthMonth = CHECK_INTEGER(1, 12);
notebook->BirthYear = CHECK_INTEGER(1950, 2021);
printf("Введите адрес:\nУлица -> "); fgets(notebook
->addresSTREET
, sizeof(notebook
->addresSTREET
), stdin
); notebook
->addresSTREET
[strcspn(notebook
->addresSTREET
, "\n")] = 0;
notebook->addresHOME = CHECK_INTEGER(1, 999);
printf("Введите номер мобильного телефона -> "); notebook->mobileNUMBER = CHECK_INTEGER(1, 999999999);
}
void UPDATE_RECORD(FILE* fPtr)
{
struct DATA notebook;
int numper;
VIEW_DATA(fPtr);
printf("Введите номер человека, данные которого нужно изменить\n-> "); /*scanf_s("%d", &numper);*/
numper = CHECK_INTEGER(1, 999);
notebook.number = numper;
ENTER_DATA(¬ebook);
fseek(fPtr
, (notebook.
number) * sizeof(struct DATA
), SEEK_SET
); fwrite(¬ebook
, sizeof(struct DATA
), 1, fPtr
); }
void ADD_RECORD(FILE* fPtr)
{
struct DATA notebook;
int ans = 1;
int numper = 0;
VIEW_DATA(fPtr);
fseek(fPtr
, 0 * sizeof(struct DATA
), SEEK_SET
); while (fread(¬ebook
, sizeof(notebook
), 1, fPtr
) == 1) {
numper++;
}
notebook.number = numper;
ENTER_DATA(¬ebook);
fseek(fPtr
, notebook.
number * sizeof(struct DATA
), SEEK_SET
); fwrite(¬ebook
, sizeof(struct DATA
), 1, fPtr
); }
void DELETE_RECORD(FILE* fPtr)
{
struct DATA notebook, blankClient = {0,"","","",0,0,0,"",0,0};
int numper = 0;
VIEW_DATA(fPtr);
printf("Введите номер человека, данные которого нужно удалить из БД\n-> "); notebook.number = numper;
fseek(fPtr
, notebook.
number * sizeof(struct DATA
), SEEK_SET
); fread(¬ebook
, sizeof(struct DATA
), 1, fPtr
); if (notebook.number == 0)
printf("Аккаунта с таким номером не существует\n"); else {
fseek(fPtr
, notebook.
number * sizeof(struct DATA
), SEEK_SET
); fwrite(&blankClient
, sizeof(struct DATA
), 1, fPtr
); }
}
void SEARCH_RECORD(FILE* readPtr)
{
struct DATA buf;
char buf2[100];
int choice;
unsigned int search_mobile=1;
bool flag = false;
char search_surname[12] = { "0" }, search_name[10] = {"0"};
printf("Осуществить поиск по:\n(1) -> Имени и Фамилии\n(2) -> Номеру телефона\n-> "); fgets(buf2
, sizeof(buf2
), stdin
); /*scanf("%s", buf2);*/
while (sscanf(buf2
, "%d", &choice
) != 1 || choice
< 0 || choice
> 2) {
printf("Неверно введено значение. Попробуйте снова ->"); // выводим сообщение об ошибке fgets(buf2
, sizeof(buf2
), stdin
); /*scanf("%s", buf2);*/ // считываем строку повторно
}
switch (choice)
{
case 1:
fgets(search_name
, sizeof(search_name
), stdin
); search_name
[strcspn(search_name
, "\n")] = 0; fgets(search_surname
, sizeof(search_surname
), stdin
); search_surname
[strcspn(search_surname
, "\n")] = 0; break;
case 2:
search_mobile = CHECK_INTEGER(1, 99999999);
break;
}
fseek(readPtr
, 0 * sizeof(struct DATA
), SEEK_SET
); while (fread(&buf
, sizeof(buf
), 1, readPtr
)) {
if ((strcmp(search_name
, buf.
name) == 0 && strcmp(search_surname
, buf.
surname) == 0) || search_mobile
== buf.
mobileNUMBER) {
printf("%-2s| %-12s | %-10s | %-15s | %-13s | %-16s | %-11s |\n", "№", "Фамилия", "Имя", "Отчество", "Дата Рождения", "Адрес", "моб.телефон");
printf("%-2d| %-12s | %-10s | %-15s | %02d.%02d.%04d | %-12s,%-3d | %-11d |\n", buf.number, buf.surname, buf.name, buf.patronymic,
buf.BirthDate, buf.BirthMonth, buf.BirthYear,
buf.addresSTREET, buf.addresHOME, buf.mobileNUMBER);
flag = true;
}
}
if (!flag)
printf("Пользователь не найден...\n"); }
void SORT_DATA(FILE* fPtr)
{
struct DATA blankClient, notebook= { 0,"","","",0,0,0,"",0,0 };
int count_rec = 0;
while (fread(¬ebook
, sizeof(notebook
), 1, fPtr
) == 1) {
count_rec++;
}
for (int a = 0; a < count_rec; a++)
{
for (int b = 0; b < count_rec -1; b++)
{
fseek(fPtr
, (b
) * sizeof(struct DATA
), SEEK_SET
); fread(¬ebook
, sizeof(struct DATA
), 1, fPtr
); fseek(fPtr
, (b
+1) * sizeof(struct DATA
), SEEK_SET
); fread(&blankClient
, sizeof(struct DATA
), 1, fPtr
); if (blankClient.number != 0)
{
if (strcmp(notebook.
surname, blankClient.
surname) > 0) {
blankClient.number--;
notebook.number++;
fseek(fPtr
, (b
) * sizeof(struct DATA
), SEEK_SET
); fwrite(&blankClient
, sizeof(struct DATA
), 1, fPtr
); fseek(fPtr
, (b
+1) * sizeof(struct DATA
), SEEK_SET
); fwrite(¬ebook
, sizeof(struct DATA
), 1, fPtr
); }
}
}
}
printf("Сортировка прошла успешно!\n"); }
I2RlZmluZSBfQ1JUX1NFQ1VSRV9OT19XQVJOSU5HUwojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHdpbmRvd3MuaD4KI2luY2x1ZGUgPGNvbmlvLmg+CgpzdHJ1Y3QgREFUQQp7CglpbnQgbnVtYmVyPTA7CgljaGFyIHN1cm5hbWVbMTJdLCBuYW1lWzEwXSwgcGF0cm9ueW1pY1sxNV07CglpbnQgQmlydGhEYXRlLCBCaXJ0aE1vbnRoLCBCaXJ0aFllYXI7CgljaGFyIGFkZHJlc1NUUkVFVFsxNl07CglpbnQgYWRkcmVzSE9NRTsKCWludCBtb2JpbGVOVU1CRVI7Cn07CgppbnQgRU5URVJfQ0hPSUNFKHZvaWQpOwp2b2lkIE5FV19EQVRBKEZJTEUqKTsKdm9pZCBWSUVXX0RBVEEoRklMRSopOwp2b2lkIEVOVEVSX0RBVEEoc3RydWN0IERBVEEqKTsKdm9pZCBVUERBVEVfUkVDT1JEKEZJTEUqKTsKdm9pZCBBRERfUkVDT1JEKEZJTEUqKTsKdm9pZCBERUxFVEVfUkVDT1JEKEZJTEUqKTsKdm9pZCBTRUFSQ0hfUkVDT1JEKEZJTEUqKTsKdm9pZCBTT1JUX0RBVEEoRklMRSopOwppbnQgQ0hFQ0tfSU5URUdFUihpbnQsaW50KTsKCmludCBtYWluKCkKewoJLy/QoNGD0YHQuNGE0LjQutCw0YbQuNGPINC60L7QvdGB0L7Qu9C4INCy0LLQvtC00LAv0LLRi9Cy0L7QtNCwCglTZXRDb25zb2xlQ1AoMTI1MSk7IC8v0YPRgdGC0LDQvdC+0LLQutCwINC60L7QtNC+0LLQvtC5INGB0YLRgNCw0L3QuNGG0Ysgd2luLWNwIDEyNTEg0LIg0L/QvtGC0L7QuiDQstCy0L7QtNCwCglTZXRDb25zb2xlT3V0cHV0Q1AoMTI1MSk7IC8v0YPRgdGC0LDQvdC+0LLQutCwINC60L7QtNC+0LLQvtC5INGB0YLRgNCw0L3QuNGG0Ysgd2luLWNwIDEyNTEg0LIg0L/QvtGC0L7QuiDQstGL0LLQvtC00LAKCglGSUxFKiBjZlB0cjsKCWNoYXIgZm5hbWVbMjBdOyAKCWludCBjaG9pY2U7CglpbnQgYWNjZXNzX21vZGU7CgoJcHJpbnRmKCLQn9GA0L7QtNC+0LvQttC40YLRjCDRgNCw0LHQvtGC0YMg0LIg0YHRgtCw0YDQvtC8INGE0LDQudC70LU/XG4iCgkJIigxKS3QlNCwICgwKS3QndC10YIsINGPINGF0L7Rh9GDINGB0L7Qt9C00LDRgtGMINC90L7QstGL0Llcbi0+Iik7CglzY2FuZigiJWQiLCAmYWNjZXNzX21vZGUpOwoKCXByaW50Zigi0JLQstC10LTQuNGC0LUg0L3QsNC30LLQsNC90LjQtSDRhNCw0LnQu9CwIChuYW1lLnR4dClcbi0+ICIpOwoJLy93aGlsZSAoZ2V0Y2hhcigpICE9ICdcbicpOwoJLy9mZ2V0cyhmbmFtZSwgc2l6ZW9mKGZuYW1lKSwgc3RkaW4pOwoJc2NhbmYoIiVbXlxuXSIsIGZuYW1lKTsKCglkbyB7CgkJc3lzdGVtKCJjbHMiKTsKCgkJaWYgKGFjY2Vzc19tb2RlID09IDEpIHsKCQkJaWYgKChjZlB0ciA9IGZvcGVuKGZuYW1lLCAicisiKSkgPT0gTlVMTCkgewoJCQkJcHJpbnRmKCJGaWxlIGNvdWxkIG5vdCBiZSBvcGVuZWQuXG4iKTsKCQkJCXJldHVybiAwOwoJCQl9CgkJfQoJCWVsc2UgewoJCQlpZiAoKGNmUHRyID0gZm9wZW4oZm5hbWUsICJ3KyIpKSA9PSBOVUxMKSB7CgkJCQlwcmludGYoIkZpbGUgY291bGQgbm90IGJlIG9wZW5lZC5cbiIpOwoJCQkJcmV0dXJuIDA7CgkJCX0KCQkJYWNjZXNzX21vZGUgPSAxOwoJCX0KCgkJY2hvaWNlID0gRU5URVJfQ0hPSUNFKCk7CgoJCXN3aXRjaCAoY2hvaWNlKQoJCXsKCQljYXNlIDA6IHJldHVybiAwOwoJCWNhc2UgMToKCQkJTkVXX0RBVEEoY2ZQdHIpOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCVZJRVdfREFUQShjZlB0cik7CgkJCWJyZWFrOwoJCWNhc2UgMzoKCQkJVVBEQVRFX1JFQ09SRChjZlB0cik7CgkJCWJyZWFrOwoJCWNhc2UgNDoKCQkJQUREX1JFQ09SRChjZlB0cik7CgkJCWJyZWFrOwoJCWNhc2UgNToKCQkJREVMRVRFX1JFQ09SRChjZlB0cik7CgkJCWJyZWFrOwoJCWNhc2UgNjoKCQkJU0VBUkNIX1JFQ09SRChjZlB0cik7CgkJCWJyZWFrOwoJCWNhc2UgNzoKCQkJU09SVF9EQVRBKGNmUHRyKTsKCQkJYnJlYWs7CgkJfQoJCWZjbG9zZShjZlB0cik7CgkJaWYgKGNob2ljZSAhPSAwKQoJCQlzeXN0ZW0oIlxucGF1c2UiKTsKCX0gd2hpbGUgKGNob2ljZSE9MCk7Cn0KCmludCBFTlRFUl9DSE9JQ0Uodm9pZCkKewoJaW50IGNob2ljZTsKCWNoYXIgYnVmWzEwMF07IC8vINGB0YLRgNC+0LrQsCDQtNC70Y8g0YHRh9C40YLRi9Cy0LDQvdC40Y8g0LLQstC10LTRkdC90L3Ri9GFINC00LDQvdC90YvRhQoKCXByaW50Zigi0JLRi9Cx0LXRgNC40YLQtSwg0YfRgtC+INCy0LDQvCDQvdGD0LbQvdC+INGB0LTQtdC70LDRgtGMXG4iCgkJIjAgLT4g0JLRi9GF0L7QtCDQuNC3INC/0YDQvtCz0YDQsNC80LzRi1xuIgoJCSIxIC0+INCh0L7Qt9C00LDQvdC40LUg0L3QvtCy0L7QuSDQsdCw0LfRiyDQtNCw0L3QvdGL0YVcbiIKCQkiMiAtPiDQn9GA0L7RgdC80L7RgtGAINGB0YPRidC10YHRgtCy0YPRjtGJ0LXQuSDQsdCw0LfRiyDQtNCw0L3QvdGL0YVcbiIKCQkiMyAtPiDQoNC10LTQsNC60YLQuNGA0L7QstCw0L3QuNC1INCx0LDQt9GLINC00LDQvdC90YvRhVxuIgoJCSI0IC0+INCU0L7Qv9C+0LvQvdC10L3QuNC1INCx0LDQt9GLINC00LDQvdC90YvRhSDQvdC+0LLRi9C80Lgg0LfQsNC/0LjRgdGP0LzQuFxuIgoJCSI1IC0+INCj0LTQsNC70LXQvdC40LUg0LfQsNC/0LjRgdC10Lkg0LjQtyDQsdCw0LfRiyDQtNCw0L3QvdGL0YVcbiIKCQkiNiAtPiDQn9C+0LjRgdC6INCyINCx0LDQt9C1INC00LDQvdC90YvRhVxuIgoJCSI3IC0+INCh0L7RgNGC0LjRgNC+0LLQutCwINC/0L7Qu9GM0LfQvtCy0LDRgtC10LvQtdC5INC/0L4g0YTQsNC80LjQu9C40Lhcbi0+ICIpOwoJLypzY2FuZigiJXMiLCBidWYpOyAqLwoJZmdldHMoYnVmLCBzaXplb2YoYnVmKSwgc3RkaW4pOy8vINGB0YfQuNGC0YvQstCw0LXQvCDRgdGC0YDQvtC60YMKCSAvLyDQv9C+0LrQsCDQstCy0L7QtCDQvdC10LrQvtGA0YDQtdC60YLQtdC9LCDRgdC+0L7QsdGJ0LDQtdC8INC+0LEg0Y3RgtC+0Lwg0Lgg0L/RgNC+0YHQuNC8INC/0L7QstGC0L7RgNC40YLRjCDQtdCz0L4KCXdoaWxlIChzc2NhbmYoYnVmLCAiJWQiLCAmY2hvaWNlKSAhPSAxIHx8IGNob2ljZSA8IDAgfHwgY2hvaWNlID4gNykKCXsKCQlwcmludGYoItCd0LXQstC10YDQvdC+INCy0LLQtdC00LXQvdC+INC30L3QsNGH0LXQvdC40LUuINCf0L7Qv9GA0L7QsdGD0LnRgtC1INGB0L3QvtCy0LAgLT4iKTsgLy8g0LLRi9Cy0L7QtNC40Lwg0YHQvtC+0LHRidC10L3QuNC1INC+0LEg0L7RiNC40LHQutC1CgkJLypzY2FuZigiJXMiLCBidWYpOyovIAoJCWZnZXRzKGJ1Ziwgc2l6ZW9mKGJ1ZiksIHN0ZGluKTsvLyDRgdGH0LjRgtGL0LLQsNC10Lwg0YHRgtGA0L7QutGDINC/0L7QstGC0L7RgNC90L4KCX0KCXJldHVybiBjaG9pY2U7Cn0KCnZvaWQgTkVXX0RBVEEoRklMRSogZlB0cikKewoJaW50IGFucyA9IDE7CglzdHJ1Y3QgREFUQSBub3RlYm9vazsKCglkb3sKCQlub3RlYm9vay5udW1iZXIrKzsKCQlFTlRFUl9EQVRBKCZub3RlYm9vayk7CgoJCWZzZWVrKGZQdHIsIG5vdGVib29rLm51bWJlciAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCQlmd3JpdGUoJm5vdGVib29rLCBzaXplb2Yoc3RydWN0IERBVEEpLCAxLCBmUHRyKTsKCQlwcmludGYoItCS0LLQtdC00LjRgtC1ICgxKSAtINGH0YLQvtCx0Ysg0LTQvtCx0LDQstC40YLRjCDQtdGJ0LUgKDApIC0g0LfQsNC60L7QvdGH0LjRgtGMXG4tPiAiKTsKCQlzY2FuZigiJWQiLCAmYW5zKTsKCX0gd2hpbGUgKGFucyAhPSAwKTsKfQoKdm9pZCBWSUVXX0RBVEEoRklMRSogcmVhZFB0cikKewoJREFUQSBidWY7CglwcmludGYoIiUtMnN8ICUtMTJzIHwgJS0xMHMgfCAlLTE1cyB8ICUtMTNzIHwgJS0xNnMgfCAlLTExcyB8XG4iLAoJCSLihJYiLCLQpNCw0LzQuNC70LjRjyIsItCY0LzRjyIsItCe0YLRh9C10YHRgtCy0L4iLCLQlNCw0YLQsCDQoNC+0LbQtNC10L3QuNGPIiwi0JDQtNGA0LXRgSIsItC80L7QsS7RgtC10LvQtdGE0L7QvSIpOwoJZnNlZWsocmVhZFB0ciwgMCAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCXdoaWxlIChmcmVhZCgmYnVmLCBzaXplb2YoYnVmKSwgMSwgcmVhZFB0cikpIHsKCgkJaWYoYnVmLm51bWJlciE9MCkKCQlwcmludGYoIiUtMmR8ICUtMTJzIHwgJS0xMHMgfCAlLTE1cyB8ICUwMmQuJTAyZC4lMDRkICAgIHwgJS0xMnMsJS0zZCB8ICUtMTFkIHxcbiIsCgkJCWJ1Zi5udW1iZXIsIGJ1Zi5zdXJuYW1lLCBidWYubmFtZSwgYnVmLnBhdHJvbnltaWMsCgkJCWJ1Zi5CaXJ0aERhdGUsIGJ1Zi5CaXJ0aE1vbnRoLCBidWYuQmlydGhZZWFyLAoJCQlidWYuYWRkcmVzU1RSRUVULCBidWYuYWRkcmVzSE9NRSwgYnVmLm1vYmlsZU5VTUJFUik7Cgl9Cn0KCmludCBDSEVDS19JTlRFR0VSKGludCBhLCBpbnQgYikKewoJY2hhciBidWZbMjU2XTsKCWludCB1c2VyX251bWJlcjsKCQoJZmdldHMoYnVmLCBzaXplb2YoYnVmKSwgc3RkaW4pOwoJd2hpbGUgKHNzY2FuZihidWYsICIlZCIsICZ1c2VyX251bWJlcikgIT0gMSB8fCB1c2VyX251bWJlciA8IGEgfHwgdXNlcl9udW1iZXIgPiBiKQoJewoJCXByaW50Zigi0J7RiNC40LHQutCwINCy0LLQvtC00LAuINCf0L7Qv9GA0L7QsdGD0LnRgtC1INC10YnQtSDRgNCw0Ldcbi0+ICIpOwoJCWZnZXRzKGJ1Ziwgc2l6ZW9mKGJ1ZiksIHN0ZGluKTsKCX0KCXJldHVybiB1c2VyX251bWJlcjsKfQoKdm9pZCBFTlRFUl9EQVRBKHN0cnVjdCBEQVRBKiBub3RlYm9vaykKewoJd2hpbGUgKGdldGNoYXIoKSAhPSAnXG4nKTsKCXByaW50Zigi0JLQstC10LTQuNGC0LUg0YTQsNC80LjQu9C40Y4gLT4gIik7CglmZ2V0cyhub3RlYm9vay0+c3VybmFtZSwgc2l6ZW9mKG5vdGVib29rLT5zdXJuYW1lKSwgc3RkaW4pOwoJbm90ZWJvb2stPnN1cm5hbWVbc3RyY3Nwbihub3RlYm9vay0+c3VybmFtZSwgIlxuIildID0gMDsKCglwcmludGYoItCS0LLQtdC00LjRgtC1INC40LzRjyAtPiAiKTsKCWZnZXRzKG5vdGVib29rLT5uYW1lLCBzaXplb2Yobm90ZWJvb2stPm5hbWUpLCBzdGRpbik7Cglub3RlYm9vay0+bmFtZVtzdHJjc3BuKG5vdGVib29rLT5uYW1lLCAiXG4iKV0gPSAwOwoKCXByaW50Zigi0JLQstC10LTQuNGC0LUg0L7RgtGH0LXRgdGC0LLQviAtPiAiKTsKCWZnZXRzKG5vdGVib29rLT5wYXRyb255bWljLCBzaXplb2Yobm90ZWJvb2stPnBhdHJvbnltaWMpLCBzdGRpbik7Cglub3RlYm9vay0+cGF0cm9ueW1pY1tzdHJjc3BuKG5vdGVib29rLT5wYXRyb255bWljLCAiXG4iKV0gPSAwOwoJCglwcmludGYoItCS0LLQtdC00LjRgtC1INC00LDRgtGDINGA0L7QttC00LXQvdC40Y86XG7QlNC10L3RjCAtPiAiKTsKCW5vdGVib29rLT5CaXJ0aERhdGU9Q0hFQ0tfSU5URUdFUigxLCAzMSk7CglwcmludGYoItCc0LXRgdGP0YYgLT4gIik7Cglub3RlYm9vay0+QmlydGhNb250aCA9IENIRUNLX0lOVEVHRVIoMSwgMTIpOwoJcHJpbnRmKCLQk9C+0LQgLT4gIik7Cglub3RlYm9vay0+QmlydGhZZWFyID0gQ0hFQ0tfSU5URUdFUigxOTUwLCAyMDIxKTsKCglwcmludGYoItCS0LLQtdC00LjRgtC1INCw0LTRgNC10YE6XG7Qo9C70LjRhtCwIC0+ICIpOwoJZmdldHMobm90ZWJvb2stPmFkZHJlc1NUUkVFVCwgc2l6ZW9mKG5vdGVib29rLT5hZGRyZXNTVFJFRVQpLCBzdGRpbik7Cglub3RlYm9vay0+YWRkcmVzU1RSRUVUW3N0cmNzcG4obm90ZWJvb2stPmFkZHJlc1NUUkVFVCwgIlxuIildID0gMDsKCglwcmludGYoItCd0L7QvNC10YAg0LTQvtC80LAgLT4gIik7Cglub3RlYm9vay0+YWRkcmVzSE9NRSA9IENIRUNLX0lOVEVHRVIoMSwgOTk5KTsKCglwcmludGYoItCS0LLQtdC00LjRgtC1INC90L7QvNC10YAg0LzQvtCx0LjQu9GM0L3QvtCz0L4g0YLQtdC70LXRhNC+0L3QsCAtPiAiKTsKCW5vdGVib29rLT5tb2JpbGVOVU1CRVIgPSBDSEVDS19JTlRFR0VSKDEsIDk5OTk5OTk5OSk7Cn0KCnZvaWQgVVBEQVRFX1JFQ09SRChGSUxFKiBmUHRyKQp7CglzdHJ1Y3QgREFUQSBub3RlYm9vazsKCWludCBudW1wZXI7CglWSUVXX0RBVEEoZlB0cik7CglwcmludGYoItCS0LLQtdC00LjRgtC1INC90L7QvNC10YAg0YfQtdC70L7QstC10LrQsCwg0LTQsNC90L3Ri9C1INC60L7RgtC+0YDQvtCz0L4g0L3Rg9C20L3QviDQuNC30LzQtdC90LjRgtGMXG4tPiAiKTsKCS8qc2NhbmZfcygiJWQiLCAmbnVtcGVyKTsqLwoJd2hpbGUgKGdldGNoYXIoKSAhPSAnXG4nKTsKCW51bXBlciA9IENIRUNLX0lOVEVHRVIoMSwgOTk5KTsKCglub3RlYm9vay5udW1iZXIgPSBudW1wZXI7CglFTlRFUl9EQVRBKCZub3RlYm9vayk7CgkKCWZzZWVrKGZQdHIsIChub3RlYm9vay5udW1iZXIpICogc2l6ZW9mKHN0cnVjdCBEQVRBKSwgU0VFS19TRVQpOwoJZndyaXRlKCZub3RlYm9vaywgc2l6ZW9mKHN0cnVjdCBEQVRBKSwgMSwgZlB0cik7Cn0KCnZvaWQgQUREX1JFQ09SRChGSUxFKiBmUHRyKQp7CglzdHJ1Y3QgREFUQSBub3RlYm9vazsKCWludCBhbnMgPSAxOwoJaW50IG51bXBlciA9IDA7CglWSUVXX0RBVEEoZlB0cik7Cglmc2VlayhmUHRyLCAwICogc2l6ZW9mKHN0cnVjdCBEQVRBKSwgU0VFS19TRVQpOwoJd2hpbGUgKGZyZWFkKCZub3RlYm9vaywgc2l6ZW9mKG5vdGVib29rKSwgMSwgZlB0cikgPT0gMSkKCXsKCQludW1wZXIrKzsKCX0KCW5vdGVib29rLm51bWJlciA9IG51bXBlcjsKCUVOVEVSX0RBVEEoJm5vdGVib29rKTsKCWZzZWVrKGZQdHIsIG5vdGVib29rLm51bWJlciAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCWZ3cml0ZSgmbm90ZWJvb2ssIHNpemVvZihzdHJ1Y3QgREFUQSksIDEsIGZQdHIpOwp9Cgp2b2lkIERFTEVURV9SRUNPUkQoRklMRSogZlB0cikKewoJc3RydWN0IERBVEEgbm90ZWJvb2ssIGJsYW5rQ2xpZW50ID0gezAsIiIsIiIsIiIsMCwwLDAsIiIsMCwwfTsKCWludCBudW1wZXIgPSAwOwoJVklFV19EQVRBKGZQdHIpOwoJcHJpbnRmKCLQktCy0LXQtNC40YLQtSDQvdC+0LzQtdGAINGH0LXQu9C+0LLQtdC60LAsINC00LDQvdC90YvQtSDQutC+0YLQvtGA0L7Qs9C+INC90YPQttC90L4g0YPQtNCw0LvQuNGC0Ywg0LjQtyDQkdCUXG4tPiAiKTsKCXNjYW5mKCIlZCIsICZudW1wZXIpOwoJbm90ZWJvb2subnVtYmVyID0gbnVtcGVyOwoJZnNlZWsoZlB0ciwgbm90ZWJvb2subnVtYmVyICogc2l6ZW9mKHN0cnVjdCBEQVRBKSwgU0VFS19TRVQpOwoJZnJlYWQoJm5vdGVib29rLCBzaXplb2Yoc3RydWN0IERBVEEpLCAxLCBmUHRyKTsKCWlmIChub3RlYm9vay5udW1iZXIgPT0gMCkKCQlwcmludGYoItCQ0LrQutCw0YPQvdGC0LAg0YEg0YLQsNC60LjQvCDQvdC+0LzQtdGA0L7QvCDQvdC1INGB0YPRidC10YHRgtCy0YPQtdGCXG4iKTsKCWVsc2UgewoJCWZzZWVrKGZQdHIsIG5vdGVib29rLm51bWJlciAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCQlmd3JpdGUoJmJsYW5rQ2xpZW50LCBzaXplb2Yoc3RydWN0IERBVEEpLCAxLCBmUHRyKTsKCX0KfQoKdm9pZCBTRUFSQ0hfUkVDT1JEKEZJTEUqIHJlYWRQdHIpCnsKCXN0cnVjdCBEQVRBIGJ1ZjsKCWNoYXIgYnVmMlsxMDBdOwoJaW50IGNob2ljZTsKCXVuc2lnbmVkIGludCBzZWFyY2hfbW9iaWxlPTE7Cglib29sIGZsYWcgPSBmYWxzZTsKCWNoYXIgc2VhcmNoX3N1cm5hbWVbMTJdID0geyAiMCIgfSwgc2VhcmNoX25hbWVbMTBdID0geyIwIn07CgoJd2hpbGUgKGdldGNoYXIoKSAhPSAnXG4nKTsKCXByaW50Zigi0J7RgdGD0YnQtdGB0YLQstC40YLRjCDQv9C+0LjRgdC6INC/0L46XG4oMSkgLT4g0JjQvNC10L3QuCDQuCDQpNCw0LzQuNC70LjQuFxuKDIpIC0+INCd0L7QvNC10YDRgyDRgtC10LvQtdGE0L7QvdCwXG4tPiAiKTsKCWZnZXRzKGJ1ZjIsIHNpemVvZihidWYyKSwgc3RkaW4pOwoJLypzY2FuZigiJXMiLCBidWYyKTsqLwoJd2hpbGUgKHNzY2FuZihidWYyLCAiJWQiLCAmY2hvaWNlKSAhPSAxIHx8IGNob2ljZSA8IDAgfHwgY2hvaWNlID4gMikKCXsKCQlwcmludGYoItCd0LXQstC10YDQvdC+INCy0LLQtdC00LXQvdC+INC30L3QsNGH0LXQvdC40LUuINCf0L7Qv9GA0L7QsdGD0LnRgtC1INGB0L3QvtCy0LAgLT4iKTsgLy8g0LLRi9Cy0L7QtNC40Lwg0YHQvtC+0LHRidC10L3QuNC1INC+0LEg0L7RiNC40LHQutC1CgkJZmdldHMoYnVmMiwgc2l6ZW9mKGJ1ZjIpLCBzdGRpbik7CgkJLypzY2FuZigiJXMiLCBidWYyKTsqLyAvLyDRgdGH0LjRgtGL0LLQsNC10Lwg0YHRgtGA0L7QutGDINC/0L7QstGC0L7RgNC90L4KCX0KCXN3aXRjaCAoY2hvaWNlKQoJewoJY2FzZSAxOgoJCXByaW50Zigi0JjQvNGPLT4gIik7CgkJd2hpbGUgKGdldGNoYXIoKSAhPSAnXG4nKTsKCQlmZ2V0cyhzZWFyY2hfbmFtZSwgc2l6ZW9mKHNlYXJjaF9uYW1lKSwgc3RkaW4pOwoJCXNlYXJjaF9uYW1lW3N0cmNzcG4oc2VhcmNoX25hbWUsICJcbiIpXSA9IDA7CgkJcHJpbnRmKCLQpNCw0LzQuNC70LjRjy0+ICIpOwoJCWZnZXRzKHNlYXJjaF9zdXJuYW1lLCBzaXplb2Yoc2VhcmNoX3N1cm5hbWUpLCBzdGRpbik7CgkJc2VhcmNoX3N1cm5hbWVbc3RyY3NwbihzZWFyY2hfc3VybmFtZSwgIlxuIildID0gMDsKCQlicmVhazsKCWNhc2UgMjoKCQlwcmludGYoItCd0L7QvNC10YAg0YLQtdC70LXRhNC+0L3QsC0+ICIpOwoJCXNlYXJjaF9tb2JpbGUgPSBDSEVDS19JTlRFR0VSKDEsIDk5OTk5OTk5KTsKCQlicmVhazsKCX0KCWZzZWVrKHJlYWRQdHIsIDAgKiBzaXplb2Yoc3RydWN0IERBVEEpLCBTRUVLX1NFVCk7Cgl3aGlsZSAoZnJlYWQoJmJ1Ziwgc2l6ZW9mKGJ1ZiksIDEsIHJlYWRQdHIpKQoJewoJCWlmICgoc3RyY21wKHNlYXJjaF9uYW1lLCBidWYubmFtZSkgPT0gMCAmJiBzdHJjbXAoc2VhcmNoX3N1cm5hbWUsIGJ1Zi5zdXJuYW1lKSA9PSAwKSB8fCBzZWFyY2hfbW9iaWxlID09IGJ1Zi5tb2JpbGVOVU1CRVIpCgkJewoJCQlwcmludGYoIiUtMnN8ICUtMTJzIHwgJS0xMHMgfCAlLTE1cyB8ICUtMTNzIHwgJS0xNnMgfCAlLTExcyB8XG4iLAoJCQkJIuKEliIsICLQpNCw0LzQuNC70LjRjyIsICLQmNC80Y8iLCAi0J7RgtGH0LXRgdGC0LLQviIsICLQlNCw0YLQsCDQoNC+0LbQtNC10L3QuNGPIiwgItCQ0LTRgNC10YEiLCAi0LzQvtCxLtGC0LXQu9C10YTQvtC9Iik7CgkJCXByaW50ZigiJS0yZHwgJS0xMnMgfCAlLTEwcyB8ICUtMTVzIHwgJTAyZC4lMDJkLiUwNGQgICAgfCAlLTEycywlLTNkIHwgJS0xMWQgfFxuIiwKCQkJCWJ1Zi5udW1iZXIsIGJ1Zi5zdXJuYW1lLCBidWYubmFtZSwgYnVmLnBhdHJvbnltaWMsCgkJCQlidWYuQmlydGhEYXRlLCBidWYuQmlydGhNb250aCwgYnVmLkJpcnRoWWVhciwKCQkJCWJ1Zi5hZGRyZXNTVFJFRVQsIGJ1Zi5hZGRyZXNIT01FLCBidWYubW9iaWxlTlVNQkVSKTsKCQkJZmxhZyA9IHRydWU7CgkJfQoJfQoJaWYgKCFmbGFnKQoJCXByaW50Zigi0J/QvtC70YzQt9C+0LLQsNGC0LXQu9GMINC90LUg0L3QsNC50LTQtdC9Li4uXG4iKTsKfQoKdm9pZCBTT1JUX0RBVEEoRklMRSogZlB0cikKewoJc3RydWN0IERBVEEgYmxhbmtDbGllbnQsIG5vdGVib29rPSB7IDAsIiIsIiIsIiIsMCwwLDAsIiIsMCwwIH07CglpbnQgY291bnRfcmVjID0gMDsKCgl3aGlsZSAoZnJlYWQoJm5vdGVib29rLCBzaXplb2Yobm90ZWJvb2spLCAxLCBmUHRyKSA9PSAxKQoJewoJCWNvdW50X3JlYysrOwoJfQoJCglmb3IgKGludCBhID0gMDsgYSA8IGNvdW50X3JlYzsgYSsrKQoJewoJCWZvciAoaW50IGIgPSAwOyBiIDwgY291bnRfcmVjIC0xOyBiKyspCgkJewoJCQlmc2VlayhmUHRyLCAoYikgKiBzaXplb2Yoc3RydWN0IERBVEEpLCBTRUVLX1NFVCk7CgkJCWZyZWFkKCZub3RlYm9vaywgc2l6ZW9mKHN0cnVjdCBEQVRBKSwgMSwgZlB0cik7CgkJCWZzZWVrKGZQdHIsIChiKzEpICogc2l6ZW9mKHN0cnVjdCBEQVRBKSwgU0VFS19TRVQpOwoJCQlmcmVhZCgmYmxhbmtDbGllbnQsIHNpemVvZihzdHJ1Y3QgREFUQSksIDEsIGZQdHIpOwoJCQlpZiAoYmxhbmtDbGllbnQubnVtYmVyICE9IDApCgkJCXsKCQkJCWlmIChzdHJjbXAobm90ZWJvb2suc3VybmFtZSwgYmxhbmtDbGllbnQuc3VybmFtZSkgPiAwKQoJCQkJewoJCQkJCWJsYW5rQ2xpZW50Lm51bWJlci0tOwoJCQkJCW5vdGVib29rLm51bWJlcisrOwoJCQkJCWZzZWVrKGZQdHIsIChiKSAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCQkJCQlmd3JpdGUoJmJsYW5rQ2xpZW50LCBzaXplb2Yoc3RydWN0IERBVEEpLCAxLCBmUHRyKTsKCQkJCQlmc2VlayhmUHRyLCAoYisxKSAqIHNpemVvZihzdHJ1Y3QgREFUQSksIFNFRUtfU0VUKTsKCQkJCQlmd3JpdGUoJm5vdGVib29rLCBzaXplb2Yoc3RydWN0IERBVEEpLCAxLCBmUHRyKTsKCQkJCX0KCQkJfQoJCX0KCX0KCXByaW50Zigi0KHQvtGA0YLQuNGA0L7QstC60LAg0L/RgNC+0YjQu9CwINGD0YHQv9C10YjQvdC+IVxuIik7Cn0=