Added ifchange function

Now can use #ifchange to only do tasks if the file changes.
main
lomna-dev 1 year ago
parent 8b272c089a
commit 617b8f0594

@ -1,8 +1,3 @@
*Compile
#do
gcc -o tasks tasks.c
*Test
#do
./tasks test.tsk
gcc -o tasks -I src src/tasks.c

@ -0,0 +1,152 @@
#ifndef INCLUDED_LOOKUP_LIST_H
#define INCLUDED_LOOKUP_LIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
// Both key and value will be string
typedef struct LookupList{
char *key;
char *value;
struct LookupList *next;
} LookupList;
// return -1 on failure
int LookupList_add(LookupList **list ,char *key, char *value){
LookupList *node = (LookupList *) malloc(sizeof(LookupList));
if(node == NULL) return -1;
node->key = key;
node->value = value;
node->next = *list;
*list = node;
return 0;
}
// Does not try to free key and value strings
void LookupList_remove(LookupList **list, char *key){
LookupList *a = *list;
if(a == NULL) return;
if(strcmp(key, a->key) == 0){
*list = (*list)->next;
free(a);
return;
}
LookupList *b = a->next;
while(b != NULL){
if(strcmp(key, b->key) == 0){
a->next = b->next;
free(b);
return;
}
a = b;
b = b->next;
}
}
char *LookupList_get(LookupList *list, char *key, char *r){
while(list != NULL){
if(strcmp(list->key, key) == 0 )
return list->value;
list = list->next;
}
return r;
}
void LookupList_print(LookupList *list){
printf("{ ");
while(list != NULL){
printf("\"%s\" : \"%s\" ,", list->key, list->value);
list = list->next;
}
printf("}\n");
}
// The binary will first have a uint32_t equal to the number of (key,value) pairs.
// Then we kill have char[] that are seperated using \0 in key1, value1, key2, value2, key3, value3 .... for all pairs.
void LookupList_store(LookupList *list, char *filename){
uint32_t n = 0;
LookupList *t = list;
while(t != NULL){
n += 1;
t = t->next;
}
t = list;
FILE *f = fopen(filename, "wb");
fwrite(&n, sizeof(uint32_t), 1, f);
for(int i = 0; i < n; i++){
size_t len_key = 0;
size_t len_value = 0;
while(t->key[len_key++] != '\0');
while(t->value[len_value++] != '\0');
fwrite(t->key, sizeof(char), len_key, f);
fwrite(t->value, sizeof(char), len_value, f);
t = t->next;
}
fclose(f);
}
void LookupList_load(LookupList **l, char *filename){
FILE *f = fopen(filename, "rb");
assert(f != NULL);
uint32_t n = 0;
fread(&n, sizeof(uint32_t), 1, f);
for(int i = 0; i < n; i++){
size_t key_capacity = 10;
char *key = (char *) malloc(sizeof(char) * key_capacity);
assert(key != NULL);
int j = 0;
while(1){
if((j+1) == key_capacity){
key_capacity *= 2;
key = (char *) realloc(key, sizeof(char) * key_capacity);
assert(key != NULL);
}
fread((key + j), sizeof(char), 1, f);
if (key[j] == '\0')
break;
j++;
}
size_t value_capacity = 10;
char *value = (char *) malloc(sizeof(char) * value_capacity);
assert(value != NULL);
j = 0;
while(1){
if((j+1) == value_capacity){
value_capacity *= 2;
value = (char *) realloc(value, sizeof(char) * value_capacity);
assert(value != NULL);
}
fread((value + j), sizeof(char), 1, f);
if (value[j] == '\0')
break;
j++;
}
LookupList_add(l, key, value);
}
fclose(f);
}
#endif

@ -0,0 +1,132 @@
#ifndef INCLUDED_SHA1_H
#define INCLUDED_SHA1_H
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
uint32_t leftRotate32( uint32_t N, uint32_t D){
return ((N << D) | (N >> (32-D)));
}
typedef struct SHA1_Result{
uint32_t h0;
uint32_t h1;
uint32_t h2;
uint32_t h3;
uint32_t h4;
} SHA1_Result;
SHA1_Result SHA1_sha1file(char *filename){
FILE* file = fopen(filename, "r");
if(file == NULL){
perror(filename);
exit(EXIT_FAILURE);
}
SHA1_Result r;
uint32_t number_of_chuncks = 0;
uint32_t size_in_bytes = 0;
uint64_t size_in_bits = 0;
uint32_t h0 = UINT32_C(0x67452301);
uint32_t h1 = UINT32_C(0xefcdab89);
uint32_t h2 = UINT32_C(0x98badcfe);
uint32_t h3 = UINT32_C(0x10325476);
uint32_t h4 = UINT32_C(0xc3d2e1f0);
size_t bytes_read;
uint8_t buffer[64];
int lastRound = 0;
while(lastRound != 1){
bytes_read = fread(buffer, 1, 64, file);
number_of_chuncks++;
if(bytes_read != 64){
// * We need to convert to 512 bit * //
size_in_bytes += bytes_read; // the final size is done here
size_in_bits = size_in_bytes * 8;
//padding
buffer[bytes_read] = 0x80;
bytes_read += 1;
for(int i = bytes_read; i <= 55; i++)
buffer[i] = 0;
//adding size to end
for(int i = 63; i >= 56; i--){
buffer[i] = size_in_bits % 256;
size_in_bits /= 256;
}
lastRound = 1; // This is the last round
}
// * We usually get a 512 bit chunk except the last chunck which we need to pad (which we do in the if above) * //
size_in_bytes += 64;
/////////////////////// ****************************************** ////////////////////////////////////////////
uint32_t w[80];
for(int i = 0; i < 16; i++)
w[i] = buffer[4*i] * 16777216 + buffer[(4*i)+1] * 65536 + buffer[(4*i)+2] * 256 + buffer[(4*i)+3];
for(int i = 16; i < 80; i++)
w[i] = leftRotate32( w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i - 16] , 1 );
uint32_t a = h0;
uint32_t b = h1;
uint32_t c = h2;
uint32_t d = h3;
uint32_t e = h4;
uint32_t f;
uint32_t k;
// The 80 iterations
for(int i = 0; i < 80; i++){
if(i >= 0 && i <= 19){
f = (b & c) ^ ((~b) & d);
k = UINT32_C(0x5a827999);
}else if ( i >= 20 && i <= 39){
f = b ^ c ^ d;
k = UINT32_C(0x6ed9eba1);
}else if (i >= 40 && i <= 59){
f = (b & c) ^ (b & d) ^ (c & d);
k = UINT32_C(0x8f1bbcdc);
}else if (i >= 60 && i <= 79){
f = b ^ c ^ d;
k = UINT32_C(0xca62c1d6);
}
uint32_t temp = leftRotate32(a,5) + f + e + k + w[i];
e = d;
d = c;
c = leftRotate32(b, 30);
b = a;
a = temp;
}
// Add this chunk's hash result
h0 = h0 + a;
h1 = h1 + b;
h2 = h2 + c;
h3 = h3 + d;
h4 = h4 + e;
/////////////////////// ****************************************** ////////////////////////////////////////////
}
fclose(file);
r.h0 = h0;
r.h1 = h1;
r.h2 = h2;
r.h3 = h3;
r.h4 = h4;
return r;
}
#endif

@ -3,6 +3,8 @@
#include <errno.h>
#include <assert.h>
#include <string.h>
#include "sha1.h"
#include "lookup_list.h"
#define MAX_TASKS 5
@ -13,6 +15,8 @@ typedef struct TASKS_str_linked_list{
struct TASKS_str_linked_list *next;
} TASKS_str_linked_list;
// sll : short for String Linked List
void TASKS_sll_print(TASKS_str_linked_list *list){
printf("[ ");
while(list != NULL){
@ -121,8 +125,10 @@ bool TASKS_get_line(FILE *f, char *line, int *current_line_capacity){
while(true){
c = fgetc(f);
if(c == EOF)
if(c == EOF){
line[i] = '\0';
return false;
}
if(c == '\n'){
line[i] = '\0';
@ -148,8 +154,11 @@ void TASKS_get_tasks(char *filename){
FILE *f = fopen(filename, "r");
assert(f != NULL);
bool to_loop = true;
bool semicolon = true;
while(TASKS_get_line(f, current_line, &current_line_capacity)){
while(to_loop){
to_loop = TASKS_get_line(f, current_line, &current_line_capacity);
TASKS_strip_line(current_line);
if(current_line[0] == '\0') continue;
@ -203,6 +212,7 @@ void TASKS_get_tasks(char *filename){
}else if(strcmp(current_section, "commands") == 0){
TASKS_sll_add(&tasks[number_of_tasks - 1].commands, TASKS_substr(current_line, 0, current_line_len - 2));
}
}
fclose(f);
@ -223,6 +233,63 @@ void TASKS_do_all_tasks(){
}
}
void TASKS_do_tasks_ifchange(char *filename){
size_t filename_size = 0;
while(filename[filename_size++] != '\0');
char *binary_filename= (char *) malloc(sizeof(char)* (filename_size+1));
binary_filename[0] = '.';
binary_filename[1] = '\0';
strcat(binary_filename, filename);
LookupList *map = NULL;
if(TASKS_file_exists(binary_filename))
LookupList_load(&map, binary_filename);
LookupList *new_map = NULL;
for(int i = 0; i < number_of_tasks; i++){
bool skip_task = true;
TASKS_str_linked_list *icll = tasks[i].ifchange;
while(icll != NULL){
char *file_sha1 = (char *) malloc(sizeof(char) * 50);
char stored_sha1[50];
SHA1_Result file_sha1_unformatted = SHA1_sha1file(icll->data);
sprintf(file_sha1, "%x%x%x%x%x",file_sha1_unformatted.h0, file_sha1_unformatted.h1,file_sha1_unformatted.h2, file_sha1_unformatted.h3, file_sha1_unformatted.h4);
strcpy(stored_sha1,LookupList_get(map, icll->data, " "));
LookupList_add(&new_map, icll->data, file_sha1);
if(strcmp(file_sha1, stored_sha1) != 0)
skip_task = false;
icll = icll->next;
}
if(map == NULL) skip_task = false;
if(skip_task) continue;
printf("[*] EXECUTING TASK : %s\n", tasks[i].name);
TASKS_str_linked_list *cll = tasks[i].commands;
while(cll != NULL){
char *cmd = cll->data;
printf("+ %s\n", cmd);
system(cmd);
cll = cll->next;
}
printf("\n");
}
if(new_map != NULL){
printf("\nSaving file named %s with sha1 values\n", binary_filename);
LookupList_print(new_map);
LookupList_store(new_map, binary_filename);
}
// MAYBE : free all char *file_sha1 after storing on disk
free(binary_filename);
}
int main(int argc, char *argv[]){
char *tasks_file = "main.tsk";
@ -249,7 +316,9 @@ int main(int argc, char *argv[]){
}
printf("\n<-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <-> <->\n\n");
//* From here we just need to execute all tasks *//
TASKS_do_all_tasks();
//* From here we just need to execute tasks *//
// TASKS_do_all_tasks();
TASKS_do_tasks_ifchange(tasks_file);
return 0;
}

@ -1,15 +0,0 @@
*Task 1
#ifchange
testfile1 testfile2
testfile3 testfile4
testfile5
#do
echo HELLO WORLD
*Task 2
#ifchange
file1 file2 file3 file4
file5 file6
file7
#do
echo HI WORLD
Loading…
Cancel
Save