aboutsummaryrefslogblamecommitdiffstats
path: root/src/cnki_kdh.c
blob: af453a7d723ac149666d21f01e673a606c76d003 (plain) (tree)
1
2
  
                                                 














                                                   

                                    
 


                                             




                                           
                     

                                     




                              
                  





                                                        
 

                                                           
 
                                              
 
                                                         



                               

                                                              
                               
 
                                



                             

                                             


                 
/*
 * Copyright (c) 2020-2023, yzrh <yzrh@noema.org>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "cnki.h"

int
cnki_kdh(cnki_t **param)
{
	if (*param == NULL)
		return 1;

	if ((*param)->stat > 0)
		printf("Begin 'KDH' decryption\n");

	long cur = ADDRESS_KDH_BODY;
	long end;

	fseek((*param)->fp_i, 0, SEEK_END);
	end = ftell((*param)->fp_i);
	fseek((*param)->fp_i, cur, SEEK_SET);

	const char key[] = KEY_KDH;
	const int key_len = KEY_KDH_LENGTH;
	long key_cur = 0;

	int buf_size;
	char buf[(*param)->size_buf];

	FILE *tmp = tmpfile();

	if (tmp == NULL)
		return 1;

	for (;;) {
		if (cur + (*param)->size_buf < end)
			buf_size = (*param)->size_buf;
		else
			buf_size = end - cur;

		fread(buf, buf_size, 1, (*param)->fp_i);

		for (int i = 0; i < buf_size; i++)
			buf[i] ^= key[key_cur++ % key_len];

		fwrite(buf, buf_size, 1, tmp);

		if ((cur = ftell((*param)->fp_i)) >= end)
			break;
	}

	if ((*param)->stat > 0)
		printf("Decrypted %ld byte(s)\n", ftell(tmp));

	fclose((*param)->fp_i);

	fseek(tmp, 0, SEEK_SET);
	(*param)->fp_i = tmp;

	cnki_pdf(param);

	if ((*param)->stat > 0)
		printf("Conversion ended\n");

	return 0;
}