0

I've been trying to make a simple password manager in c for university. The code is below.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
  char *group;
  char *name;
  char *username;
  char *password;
  char *date;
  long int unixTime;
} FileEntry;

void printEntry(FileEntry entry);
FileEntry show(char filename[], char p_name[]);
int write_entry(char filename[], FileEntry entry);

int main(int argc, char **argv) {
  FileEntry test = {"bank", "revolut", "date", "1322"};
  write_entry("test.txt", test);
  FileEntry te;
  te = show("test.txt", "revolut");
  printEntry(te);
  /* printf("%s\n", te.name); */
  /* printf("%s\n", te.group); */
  /* printf("%s\n", te.username); */
  /* printf("%s\n", te.password); */
  /* printf("%ld\n", te.unixTime); */
  /* printf("%s\n", te.date); */

  return 0;
}

void printEntry(FileEntry entry) {
  printf("Group = %s\n", entry.group);
  printf("Name = %s\n", entry.name);
  printf("Username = %s\n", entry.username);
  printf("Password = %s\n", entry.password);
  printf("UnixTime = %ld\n", entry.unixTime);
  printf("Date = %s\n", entry.date);
}

FileEntry show(char filename[], char p_name[]) {
  FILE *fptr = NULL;
  fptr = fopen(filename, "r");
  if(fptr == NULL) {
    fprintf(stderr, "Error file %s does not exist.\nCreate a file first.\n", filename);
  }
  char chunk[256];
  FileEntry entry;
  while(fgets(chunk, sizeof(chunk), fptr)) {
    printf("%s", chunk);

    char *saveptr;
    char *group = strtok_r(chunk, "\t", &saveptr);
    char *name = strtok_r(NULL, "\t", &saveptr);
    long int date = atoi(strtok_r(NULL, "\t", &saveptr));
    char *username = strtok_r(NULL, "\t", &saveptr);
    char *password = strtok_r(NULL, "\t", &saveptr);
    password[strcspn(password, "\n")] = 0;

    if(!strcmp(name, p_name)) {
      entry.name = name;
      entry.group = group;
      entry.username = username;
      entry.password = password;
      entry.unixTime = date;

      struct tm *info;
      char buf[100];
      info = localtime(&entry.unixTime);
      strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S", info);

      entry.date = buf;
      printf("%s\n", buf);
      break;
    }
  }
  printEntry(entry);
  return entry;
}

int write_entry(char filename[], FileEntry entry) {
  FILE *fptr = NULL;
  fptr = fopen(filename, "r");
  if(fptr == NULL) {
    printf("File does not exist. Creating file %s...\n", filename);
  }
  fptr = fopen(filename, "a");
  if(fptr == NULL) {
    printf("Error opening file\n");
  }
  fptr = fopen(filename, "a");

  // Get current time in Unix timestamp
  time_t t = time(NULL);
  // Add encryption here
  fprintf(fptr, "%s\t%s\t%ld\t%s\t%s\t\n", entry.group, entry.name, t, entry.username, entry.password);

  fclose(fptr);
  return 0;
}

In the show function I'm trying to read the file that holds the passwords find the one that matches the name given to it and return a struct FileEntry with all the information. The data are written in the file in the format: Group\tName\tDateTime\tUsername\tPassword\t\n in order to read them using the strtok function. The problem is that the information prints fine inside the function but not in the main function. It either does not print anything or prints half of it. I can't find what is causing it. Thanks in advance.

  • The struct has references to the local variable `char chunk[256];`. Local variables are only valid within the function. Trying to access such references outside the function is Undefined Behaviour. Make a copy of the strings if you really want to do that. – kaylum Jun 03 '22 at 00:21
  • 1
    `strtok_r` returns pointers to the original buffer. You have to copy the strings to new buffer (`strdup()` will be useful if it is available in your environment). – MikeCAT Jun 03 '22 at 00:21
  • Yes this was the solution. Thaks – TasosFrago Jun 03 '22 at 00:40

0 Answers0