proxmark3/client/loclass/fileutils.c

166 lines
4.5 KiB
C

/*****************************************************************************
* WARNING
*
* THIS CODE IS CREATED FOR EXPERIMENTATION AND EDUCATIONAL USE ONLY.
*
* USAGE OF THIS CODE IN OTHER WAYS MAY INFRINGE UPON THE INTELLECTUAL
* PROPERTY OF OTHER PARTIES, SUCH AS INSIDE SECURE AND HID GLOBAL,
* AND MAY EXPOSE YOU TO AN INFRINGEMENT ACTION FROM THOSE PARTIES.
*
* THIS CODE SHOULD NEVER BE USED TO INFRINGE PATENTS OR INTELLECTUAL PROPERTY RIGHTS.
*
*****************************************************************************
*
* This file is part of loclass. It is a reconstructon of the cipher engine
* used in iClass, and RFID techology.
*
* The implementation is based on the work performed by
* Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and
* Milosch Meriac in the paper "Dismantling IClass".
*
* Copyright (C) 2014 Martin Holst Swende
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
*
*
*
****************************************************************************/
#ifndef ON_DEVICE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdarg.h>
#include "fileutils.h"
#include "ui.h"
/**
* @brief checks if a file exists
* @param filename
* @return
*/
int fileExists(const char *filename) {
#ifdef _WIN32
struct _stat st;
int result = _stat(filename, &st);
#else
struct stat st;
int result = stat(filename, &st);
#endif
return result == 0;
}
int saveFile(const char *preferredName, const char *suffix, const void* data, size_t datalen)
{
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
char * fileName = malloc(size);
memset(fileName, 0, size);
int num = 1;
sprintf(fileName,"%s.%s", preferredName, suffix);
while (fileExists(fileName)) {
sprintf(fileName,"%s-%d.%s", preferredName, num, suffix);
num++;
}
/* We should have a valid filename now, e.g. dumpdata-3.bin */
/*Opening file for writing in binary mode*/
FILE *f = fopen(fileName, "wb");
if (!f) {
prnlog("File not found or locked. '%s'", fileName);
free(fileName);
return 1;
}
fwrite(data, 1, datalen, f);
fflush(f);
fclose(f);
prnlog("Saved %u bytes to binary file %s", datalen, fileName);
free(fileName);
return 0;
}
int saveFileEML(const char *preferredName, const char *suffix, uint8_t* data, size_t datalen, size_t blocksize) {
if ( preferredName == NULL ) return 1;
if ( suffix == NULL ) return 1;
if ( data == NULL ) return 1;
int retval = 0;
int blocks = datalen/blocksize;
int i,j;
int size = sizeof(char) * (strlen(preferredName) + strlen(suffix) + 10);
char * fileName = malloc(size);
memset(fileName, 0, size);
int num = 1;
sprintf(fileName,"%s.%s", preferredName, suffix);
while (fileExists(fileName)) {
sprintf(fileName,"%s-%d.%s", preferredName, num, suffix);
num++;
}
/* We should have a valid filename now, e.g. dumpdata-3.bin */
/*Opening file for writing in text mode*/
FILE *f = fopen(fileName, "w+");
if (!f) {
prnlog("File not found or locked. '%s'", fileName);
retval = 1;
goto out;
}
for (i = 0; i < datalen; i++) {
fprintf(f, "%02X", data[i] );
if ( (i+1) % 4 == 0)
fprintf(f, "\n");
}
// left overs
if ( datalen % blocksize != 0) {
int index = blocks * blocksize;
for (j = 0; j < datalen % blocksize; j++) {
fprintf(f, "%02X", data[index + j] );
}
}
fflush(f);
fclose(f);
prnlog("Saved %d blocks to text file %s", blocks, fileName);
out:
free(fileName);
return retval;
}
/**
* Utility function to print to console. This is used consistently within the library instead
* of printf, but it actually only calls printf (and adds a linebreak).
* The reason to have this method is to
* make it simple to plug this library into proxmark, which has this function already to
* write also to a logfile. When doing so, just delete this function.
* @param fmt
*/
void prnlog(char *fmt, ...)
{
char buffer[2048] = {0};
va_list args;
va_start(args,fmt);
vsprintf (buffer,fmt, args);
va_end(args);
PrintAndLog(buffer);
}
#else //if we're on ARM
void prnlog(char *fmt,...)
{
return;
}
#endif