From aa22ed1bcdd3a06638368f56092f53ba80c2a52e Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Mon, 4 Nov 2024 21:06:30 +0700 Subject: [PATCH 1/9] feat: init touch and mkdir --- lib/command/impls/mkdir.ts | 12 ++++++++++++ lib/command/impls/touch.ts | 12 ++++++++++++ lib/command/impls/types.ts | 2 ++ lib/command/index.ts | 8 ++++++++ 4 files changed, 34 insertions(+) create mode 100644 lib/command/impls/mkdir.ts create mode 100644 lib/command/impls/touch.ts diff --git a/lib/command/impls/mkdir.ts b/lib/command/impls/mkdir.ts new file mode 100644 index 0000000..50469a5 --- /dev/null +++ b/lib/command/impls/mkdir.ts @@ -0,0 +1,12 @@ +import { formatArg } from '../utils'; +import type { CommandFunc } from './types'; + +export const mkdir: CommandFunc = async function(...args) { + // discard `mkdir` + args.shift(); + // discard first space + args.shift(); + + return [ + ]; +}; diff --git a/lib/command/impls/touch.ts b/lib/command/impls/touch.ts new file mode 100644 index 0000000..994625c --- /dev/null +++ b/lib/command/impls/touch.ts @@ -0,0 +1,12 @@ +import { formatArg } from '../utils'; +import type { CommandFunc } from './types'; + +export const touch: CommandFunc = async function(...args) { + // discard `touch` + args.shift(); + // discard first space + args.shift(); + + return [ + ]; +}; diff --git a/lib/command/impls/types.ts b/lib/command/impls/types.ts index 096b1af..be4e191 100644 --- a/lib/command/impls/types.ts +++ b/lib/command/impls/types.ts @@ -7,4 +7,6 @@ export enum Command { SU = 'su', LS = 'ls', USERADD = 'useradd', + TOUCH = 'touch', + MKDIR = 'mkdir', } diff --git a/lib/command/index.ts b/lib/command/index.ts index 3c19ea9..d6824a8 100644 --- a/lib/command/index.ts +++ b/lib/command/index.ts @@ -8,6 +8,8 @@ import { cd } from './impls/cd'; import { su } from './impls/su'; import { ls } from './impls/ls'; import { useradd } from './impls/useradd'; +import { touch } from './impls/touch'; +import { mkdir } from './impls/mkdir'; export async function execute(command: string): Promise { const args = parse(command); @@ -37,6 +39,12 @@ export async function execute(command: string): Promise { case Command.USERADD: res = await useradd(...args as any); break; + case Command.TOUCH: + res = await touch(...args as any); + break; + case Command.MKDIR: + res = await mkdir(...args as any); + break; default: res = echo('echo', ' ', `Unknown command:\\u001b[31m ${args[0]}`); break; From 32b527ee8cb1b5c13611d59989e6372779b021aa Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Mon, 4 Nov 2024 21:08:22 +0700 Subject: [PATCH 2/9] feat: add createFolder to fileService --- services/files.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/files.ts b/services/files.ts index 0716744..25fb861 100644 --- a/services/files.ts +++ b/services/files.ts @@ -69,6 +69,8 @@ export const fileService = { }, async createFile(filename: string): Promise> { }, + async createFolder(filename: string): Promise> { + }, async changeDirectory(filename: string): Promise> { try { const { cwd, switchCwd } = useCwdStore(); From 33b3a866e8aa633873dd8d2598923f41ac45bf53 Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:19:16 +0700 Subject: [PATCH 3/9] feat: init umask --- lib/command/impls/help.ts | 6 ++++++ lib/command/impls/types.ts | 1 + 2 files changed, 7 insertions(+) diff --git a/lib/command/impls/help.ts b/lib/command/impls/help.ts index e3c7e81..a25a8cc 100644 --- a/lib/command/impls/help.ts +++ b/lib/command/impls/help.ts @@ -45,6 +45,12 @@ const commandDescriptions: Record = { { args: ['-u ', '-p '] }, ], }, + [Command.UMASK]: { + description: 'Set file mode creation mask', + usages: [ + { args: ['()?'] }, + ], + }, }; function getDescription(commandName: string): string[] { diff --git a/lib/command/impls/types.ts b/lib/command/impls/types.ts index be4e191..7a710db 100644 --- a/lib/command/impls/types.ts +++ b/lib/command/impls/types.ts @@ -9,4 +9,5 @@ export enum Command { USERADD = 'useradd', TOUCH = 'touch', MKDIR = 'mkdir', + UMASK = 'umask', } From e1e0529435cc45ad487733b6d8b8ced02d4c6fd6 Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:22:16 +0700 Subject: [PATCH 4/9] feat: init umask command --- composables/umask.ts | 0 lib/command/impls/umask.ts | 21 +++++++++++++++++++++ lib/command/index.ts | 4 ++++ 3 files changed, 25 insertions(+) create mode 100644 composables/umask.ts create mode 100644 lib/command/impls/umask.ts diff --git a/composables/umask.ts b/composables/umask.ts new file mode 100644 index 0000000..e69de29 diff --git a/lib/command/impls/umask.ts b/lib/command/impls/umask.ts new file mode 100644 index 0000000..500a71d --- /dev/null +++ b/lib/command/impls/umask.ts @@ -0,0 +1,21 @@ +import { formatArg } from '../utils'; +import type { CommandFunc } from './types'; + +export const umask: CommandFunc = async function(...args) { + // discard `umask` + args.shift(); + // discard first space + args.shift(); + + if (args.length === 0) { + return []; + } + + if (args.length > 1) { + const umask = formatArg(args[0]); + return []; + } + + return [ + ]; +}; diff --git a/lib/command/index.ts b/lib/command/index.ts index d6824a8..50c5fcb 100644 --- a/lib/command/index.ts +++ b/lib/command/index.ts @@ -10,6 +10,7 @@ import { ls } from './impls/ls'; import { useradd } from './impls/useradd'; import { touch } from './impls/touch'; import { mkdir } from './impls/mkdir'; +import { umask } from './impls/umask'; export async function execute(command: string): Promise { const args = parse(command); @@ -45,6 +46,9 @@ export async function execute(command: string): Promise { case Command.MKDIR: res = await mkdir(...args as any); break; + case Command.UMASK: + res = await umask(...args as any); + break; default: res = echo('echo', ' ', `Unknown command:\\u001b[31m ${args[0]}`); break; From 837528185114573b4827b9bd0f04d3f5b176bc5f Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:24:19 +0700 Subject: [PATCH 5/9] feat: umask store --- composables/umask.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/composables/umask.ts b/composables/umask.ts index e69de29..7e64c91 100644 --- a/composables/umask.ts +++ b/composables/umask.ts @@ -0,0 +1,16 @@ +import { createGlobalState } from '@vueuse/core'; + +export const useUmaskStore = createGlobalState(() => { + const umask = ref(window?.localStorage?.getItem('umask') || '002'); + function changeUmask(newUmask: string) { + umask.value = newUmask; + } + function clearUmask() { + umask.value = '002'; + } + return { + umask, + changeUmask, + clearUmask, + }; +}); From acbfefb3f037c53e1ce58d18ce595aeae0104c4b Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:26:19 +0700 Subject: [PATCH 6/9] fix: change internal umask representation --- composables/umask.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/composables/umask.ts b/composables/umask.ts index 7e64c91..5abada1 100644 --- a/composables/umask.ts +++ b/composables/umask.ts @@ -1,12 +1,12 @@ import { createGlobalState } from '@vueuse/core'; export const useUmaskStore = createGlobalState(() => { - const umask = ref(window?.localStorage?.getItem('umask') || '002'); - function changeUmask(newUmask: string) { + const umask = ref(window?.localStorage?.getItem('umask') || '000000000010'); + function changeUmask(newUmask: string & { length: 12 } & { [index: number]: '0' | '1' }) { umask.value = newUmask; } function clearUmask() { - umask.value = '002'; + umask.value = '000000000010'; } return { umask, From 166db606709bf04934552fc8f181878d429c41cf Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:40:46 +0700 Subject: [PATCH 7/9] feat: basic umask command --- lib/command/impls/umask.ts | 43 +++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/command/impls/umask.ts b/lib/command/impls/umask.ts index 500a71d..28b4242 100644 --- a/lib/command/impls/umask.ts +++ b/lib/command/impls/umask.ts @@ -8,14 +8,51 @@ export const umask: CommandFunc = async function(...args) { args.shift(); if (args.length === 0) { - return []; + const { umask } = useUmaskStore(); + return [umaskToOct(umask.value)]; } if (args.length > 1) { - const umask = formatArg(args[0]); - return []; + return [ + 'Invalid use of umask. Run \'help umask\'', + ]; } + const umask = formatArg(args[0]); + if (umask.length !== 3 || !isOctDigit(umask[0]) || !isOctDigit(umask[1]) || !isOctDigit(umask[2])) { + return ['Invalid umask']; + } + const { changeUmask } = useUmaskStore(); + changeUmask(umaskFromOct(umask as any)); return [ + 'Change umask successfully', ]; }; + +function isOctDigit(c: string): boolean { + const n = Number.parseInt(c); + return c.length === 1 && 0 <= n && n <= 7; +} + +function umaskToOct(umask: string): string { + const ownerRead = Number.parseInt(umask[3]); + const ownerWrite = Number.parseInt(umask[4]); + const ownerExecute = Number.parseInt(umask[5]); + const ownerOct = ownerRead * 4 + ownerWrite * 2 + ownerExecute; + const groupRead = Number.parseInt(umask[6]); + const groupWrite = Number.parseInt(umask[7]); + const groupExecute = Number.parseInt(umask[8]); + const groupOct = groupRead * 4 + groupWrite * 2 + groupExecute; + const otherRead = Number.parseInt(umask[9]); + const otherWrite = Number.parseInt(umask[10]); + const otherExecute = Number.parseInt(umask[11]); + const otherOct = otherRead * 4 + otherWrite * 2 + otherExecute; + return `${ownerOct}${groupOct}${otherOct}`; +} + +function umaskFromOct(octs: string): string { + const ownerOct = octs[0]; + const groupOct = octs[1]; + const otherOct = octs[2]; + return `000${ownerOct.toString(2).padStart(3, '0')}${groupOct.toString(2).padStart(3, '0')}${otherOct.toString(2).padStart(3, '0')}`; +} From 8b1144905dc219662a87185470f108c912f6ef42 Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:41:28 +0700 Subject: [PATCH 8/9] feat: persist changed umask --- composables/umask.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composables/umask.ts b/composables/umask.ts index 5abada1..d9d2f73 100644 --- a/composables/umask.ts +++ b/composables/umask.ts @@ -4,9 +4,11 @@ export const useUmaskStore = createGlobalState(() => { const umask = ref(window?.localStorage?.getItem('umask') || '000000000010'); function changeUmask(newUmask: string & { length: 12 } & { [index: number]: '0' | '1' }) { umask.value = newUmask; + localStorage.setItem('umask', newUmask); } function clearUmask() { umask.value = '000000000010'; + localStorage.setItem('umask', umask.value); } return { umask, From f1fbb90793c6e4b1554961fdfa7106c8030c1120 Mon Sep 17 00:00:00 2001 From: Huy-DNA Date: Tue, 5 Nov 2024 11:42:44 +0700 Subject: [PATCH 9/9] feat: clear umask when switching users --- composables/user.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/composables/user.ts b/composables/user.ts index 15eb397..c8de507 100644 --- a/composables/user.ts +++ b/composables/user.ts @@ -1,6 +1,7 @@ import { createGlobalState } from '@vueuse/core'; export const useUserStore = createGlobalState(() => { + const { clearUmask } = useUmaskStore(); const username = ref(window?.localStorage?.getItem('username') || 'guest'); onMounted(async () => { if (username.value === 'guest') { @@ -19,6 +20,7 @@ export const useUserStore = createGlobalState(() => { function switchUser(name: string) { username.value = name; localStorage.setItem('username', name); + clearUmask(); } watch(username, async () => { const meta = (await useFetch('/api/users', {