I'm working on a program that takes the output from a script, stores it and prints the output in a certain way, more specificly either: (first name, middle/surname, key) or(middle/surname, first name, key) etc...
So I wrote the program, but I keep getting segmentation fail when I try to run it. The compilations is fine and the script works, because I tested it.
Any suggestions on what could be done different or improved?
code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
struct memberinfo {
char firstname[250]; // all names except last name
char surname [100]; // surname
int pub_key; // 0 if the user does not have a key
};
typedef struct memberinfo acc_t;
int counter = 0;
void les_data (acc_t *classlist);
void skriv_data (acc_t *classlist, char * select);
int main(int argc, char *argv[]) {
acc_t classlist[200];
char *ch = NULL;
if(argc == 2){//checking for additional argument on execute
ch = argv[1];//pointer becomes main argument
}
else if(argc < 2){//if there is less then 2 arguments
ch = getenv("V1");//pointer gets the default environmental variable.
}
else{//same as above, this just makes sure that "ch" don't return with NULL value
argc == 1;
ch = getenv("V1");
}
read_data (classlist);//calling the method for executing the script and store output
print_data(classlist, ch);//calling the method for printing the data
return 0;
}
void read_data(acc_t *classlist) {
FILE * list;
char *name, *fname, *lname, *tmp;
char usertmp[1000], buffer[BUFSIZ+1];//usertmp = temporary list, buffer contain the scripts output
int cnt, i, chars_read;
memset(buffer, '\0', sizeof(buffer));//memsetting buffer with all 0
list = popen("./classlist.sh", "r");//opening and running the script in a read mode
while(list!=NULL){ //if list is not NULL, we begin to read from it
chars_read = fread(buffer, sizeof(char), BUFSIZ, list);//reading from scripts output,
//storing in buffer.
while(chars_read >0){
//while there are still characters in file we do:
tmp = buffer;//setting pointer to the text stored in buffer
for(i = 0; tmp[i]!= '\n'; i++){//for-loop running until a new line is detected
if(tmp[i]== ' '){ //if there is a space in text the counter increases
cnt++;
}//if end
}//for-loop end
name = strtok(buffer,": ");//the complete name is taken from the text in buffer
strcpy(usertmp, name);//the name is copied to usertmp array
for(i = 0; i <(cnt-2); i++){//for-loop
name = strtok(NULL, ": ");
strcat(strcat(usertmp, " "), name); //nested strcat??
}//for-loop end // saves the whole name in usertmp[]
name = NULL;//setting name to null, clearing the memmory
strcpy(classlist[counter].firstname, name);//copying first name in array
name = strtok(NULL, ": ");//setting to NULL to skip first name
strcpy(classlist[counter].surname, usertmp);//copy middle/last name
name = strtok(NULL, ": ");//setting to null to skipp the middle/last name
classlist[counter].pub_key = atoi(name);//copy the int key to array
counter ++;
}//if(chars_read) end
pclose(list);
}//while end
}//read_data end
void print_data (acc_t *classlist, char *select) {
switch (select[0])
{
case 'k':
printf("%s %s %d\n", classlist[counter].firstname, classlist[counter].surname,
classlist[counter].pub_key);
//printf("Printing out class data:\n");
break;
default:
break;
}
}
So the script prints a group of members like this:
Script:
#! /bin/bash
grep da2001-2020 /etc/group |cut -f4 -d: > group.txt
#Getting a list of members
tr -s ',' '\n' < group.txt |sort -k 1 -t',' -n > snm.txt
#putting numbers in a order
sed 's/^.//' snm.txt > cnm.txt
#removing "s" in front of student number.
rm group.txt #delting group file
cut -f1,5 -d: /etc/passwd |cut -f1 -d, |sort -u > big_list.txt
#extracting names from file
grep -f snm.txt big_list.txt > final.txt
#comparing the two lists
wc -l < final.txt > amount.txt
#counting students
for id in $(cat cnm.txt);
#scaning student numbers that were selected
do
File=$(curl -k --silent -q https://website.com/~$id/pub_key.asc| grep -o
"BEGIN PGP PUBLIC KEY BLOCK")
#curling a request for file indicator pub_key.asc
if [ "$File" ];
then
grep "$id" final.txt | cut -f2 -d: | sort > verification.txt
echo -e "$(cat verification.txt): 1 " #indicating has key
#placing the students who have a key in a file with indicator
else
grep "$id" final.txt | cut -f2 -d: | sort > verification.txt
echo -e "$(cat verification.txt): 0 " #indicator no key
#placing the students who dont have key in a file with indicator
fi
done 2>&1 | tee classlist.txt #exit loop, print and save output file
rm amount.txt
rm cnm.txt
rm big_list.txt
rm snm.txt
rm verification.txt
rm final.txt