Reviewed-on: suwako/sp#17
このコミットが含まれているのは:
コミット
45dc3ac6dc
|
@ -11,6 +11,7 @@
|
||||||
* ヘルプの表示の削除 (manpageをご利用下さい)
|
* ヘルプの表示の削除 (manpageをご利用下さい)
|
||||||
* パスワード作成関数のデフォルトな長さは64に
|
* パスワード作成関数のデフォルトな長さは64に
|
||||||
* manpageを細かくに
|
* manpageを細かくに
|
||||||
|
* パスワードがなくなるまで削除したら、ディレクトリも削除する様に
|
||||||
|
|
||||||
# 1.2.0
|
# 1.2.0
|
||||||
* やっとTOTP機能性を修正した
|
* やっとTOTP機能性を修正した
|
||||||
|
|
130
src/delpass.c
130
src/delpass.c
|
@ -1,8 +1,91 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "delpass.h"
|
#include "delpass.h"
|
||||||
|
|
||||||
|
int delcnt(const char *str, char delimiter) {
|
||||||
|
int count = 0;
|
||||||
|
while (*str) {
|
||||||
|
if (*str == delimiter) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **explode(const char *str, char delimiter, int *numtokens) {
|
||||||
|
int count = delcnt(str, delimiter) + 1;
|
||||||
|
*numtokens = count;
|
||||||
|
|
||||||
|
char **tokens = malloc(count * sizeof(char *));
|
||||||
|
if (tokens == NULL) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strcopy = strdup(str);
|
||||||
|
if (strcopy == NULL) {
|
||||||
|
perror("strdup");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *token = strtok(strcopy, &delimiter);
|
||||||
|
int i = 0;
|
||||||
|
while (token != NULL) {
|
||||||
|
tokens[i] = strdup(token);
|
||||||
|
if (tokens[i] == NULL) {
|
||||||
|
perror("strdup");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
token = strtok(NULL, &delimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(strcopy);
|
||||||
|
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freetokens(char **tokens, int numtokens) {
|
||||||
|
for (int i = 0; i < numtokens; i++) {
|
||||||
|
free(tokens[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dirisempty(char *path) {
|
||||||
|
struct dirent *entry;
|
||||||
|
int res = false;
|
||||||
|
|
||||||
|
DIR *dir = opendir(path);
|
||||||
|
if (dir == NULL) {
|
||||||
|
perror("opendir");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((entry = readdir(dir))) {
|
||||||
|
if (
|
||||||
|
entry->d_name[0] == '.' &&
|
||||||
|
entry->d_name[1] == '\0' &&
|
||||||
|
entry->d_name[1] == '.' &&
|
||||||
|
entry->d_name[2] == '\0'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
res++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return res != 0;
|
||||||
|
}
|
||||||
|
|
||||||
int delpass(char *file, int force) {
|
int delpass(char *file, int force) {
|
||||||
char *lang = getlang();
|
char *lang = getlang();
|
||||||
|
|
||||||
|
@ -30,7 +113,6 @@ int delpass(char *file, int force) {
|
||||||
|
|
||||||
// ファイルが既に存在するかどうか確認
|
// ファイルが既に存在するかどうか確認
|
||||||
snprintf(gpgpathchk, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
snprintf(gpgpathchk, alllen, "%s%s%s%s", homedir, basedir, file, ext);
|
||||||
|
|
||||||
if (access(gpgpathchk, F_OK) != 0) {
|
if (access(gpgpathchk, F_OK) != 0) {
|
||||||
if (strncmp(lang, "en", 2) == 0)
|
if (strncmp(lang, "en", 2) == 0)
|
||||||
perror("Password does not exist");
|
perror("Password does not exist");
|
||||||
|
@ -79,6 +161,52 @@ int delpass(char *file, int force) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 空のディレクトリの場合
|
||||||
|
int numt;
|
||||||
|
char **tokens = explode(file, '/', &numt);
|
||||||
|
|
||||||
|
char basepath[1024];
|
||||||
|
char passpath[1024];
|
||||||
|
snprintf(basepath, sizeof(basepath), "%s%s", homedir, basedir);
|
||||||
|
snprintf(passpath, sizeof(passpath), "%s%s%s", homedir, basedir, tokens[0]);
|
||||||
|
char *ls = strrchr(basepath, '/');
|
||||||
|
if (ls != NULL) {
|
||||||
|
*ls = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: ここはメモリに関するバグが起こっている為、未だmasterに入れない
|
||||||
|
for (int i = 1; i < numt; i++) {
|
||||||
|
if (i == (numt-1)) continue;
|
||||||
|
strncat(passpath, "/", sizeof(passpath) - strlen(passpath) - 1);
|
||||||
|
strncat(passpath, tokens[i], sizeof(passpath) - strlen(passpath) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = numt - 1; i >= 0; i--) {
|
||||||
|
// ~/.local/share/sp を削除したら危険
|
||||||
|
if (strncmp(passpath, basepath, sizeof(passpath)) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ディレクトリが空じゃない場合、やめろ
|
||||||
|
if (!dirisempty(passpath)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rmdir(passpath) == -1) {
|
||||||
|
if (strncmp(lang, "en", 2) == 0) perror("Failed to deleding directory");
|
||||||
|
else perror("ディレクトリを削除に失敗");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *last_slash = strrchr(passpath, '/');
|
||||||
|
if (last_slash != NULL) {
|
||||||
|
*last_slash = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freetokens(tokens, numt);
|
||||||
|
|
||||||
|
// sp -e の場合、「パスワードを削除しました」って要らない
|
||||||
if (force == 1) return 0;
|
if (force == 1) return 0;
|
||||||
|
|
||||||
if (strncmp(lang, "en", 2) == 0) puts("Deleted password");
|
if (strncmp(lang, "en", 2) == 0) puts("Deleted password");
|
||||||
|
|
読み込み中…
新しいイシューから参照