mirror of
https://github.com/gechandesu/pwd.git
synced 2026-02-13 04:21:50 +03:00
init
This commit is contained in:
8
.editorconfig
Normal file
8
.editorconfig
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.v]
|
||||||
|
indent_style = tab
|
||||||
8
.gitattributes
vendored
Normal file
8
.gitattributes
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
|
*.bat eol=crlf
|
||||||
|
|
||||||
|
*.v linguist-language=V
|
||||||
|
*.vv linguist-language=V
|
||||||
|
*.vsh linguist-language=V
|
||||||
|
v.mod linguist-language=V
|
||||||
|
.vdocignore linguist-language=ignore
|
||||||
48
.github/workflows/docs.yaml
vendored
Normal file
48
.github/workflows/docs.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
name: Docs
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup V
|
||||||
|
run: |
|
||||||
|
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||||
|
unzip -q /tmp/v.zip -d /tmp
|
||||||
|
echo /tmp/v >> "$GITHUB_PATH"
|
||||||
|
|
||||||
|
- name: Build docs
|
||||||
|
run: |
|
||||||
|
v doc -f html -m .
|
||||||
|
pushd _docs
|
||||||
|
ln -vs ${{ github.event.repository.name }}.html index.html
|
||||||
|
ls -alFh
|
||||||
|
popd
|
||||||
|
|
||||||
|
- name: Upload static files as artifact
|
||||||
|
id: deployment
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: _docs/
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
needs: build
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
24
.github/workflows/test.yaml
vendored
Normal file
24
.github/workflows/test.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: Tests
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup V
|
||||||
|
run: |
|
||||||
|
wget -qO /tmp/v.zip https://github.com/vlang/v/releases/latest/download/v_linux.zip
|
||||||
|
unzip -q /tmp/v.zip -d /tmp
|
||||||
|
echo /tmp/v >> "$GITHUB_PATH"
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: |
|
||||||
|
v -stats test .
|
||||||
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Binaries for programs and plugins
|
||||||
|
main
|
||||||
|
pwd
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
*.dll
|
||||||
|
|
||||||
|
# Ignore binary output folders
|
||||||
|
bin/
|
||||||
|
|
||||||
|
# Ignore common editor/system specific metadata
|
||||||
|
.DS_Store
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# ENV
|
||||||
|
.env
|
||||||
|
|
||||||
|
# vweb and database
|
||||||
|
*.db
|
||||||
|
*.js
|
||||||
8
README.md
Normal file
8
README.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Access to the UNIX Password Database
|
||||||
|
|
||||||
|
`pwd` module provides thread-safe access to the UNIX user account and password
|
||||||
|
database.
|
||||||
|
|
||||||
|
See [passwd(5)](https://man7.org/linux/man-pages/man5/passwd.5.html),
|
||||||
|
[getpwent(3)](https://man7.org/linux/man-pages/man3/getpwent.3.html) and
|
||||||
|
[getpwnam(3)](https://man7.org/linux/man-pages/man3/getpwnam.3.html) for info.
|
||||||
22
UNLICENSE
Normal file
22
UNLICENSE
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||||
|
software, either in source code form or as a compiled binary, for any purpose,
|
||||||
|
commercial or non-commercial, and by any means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||||
|
software dedicate any and all copyright interest in the software to the public
|
||||||
|
domain. We make this dedication for the benefit of the public at large and to
|
||||||
|
the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of relinquishment in
|
||||||
|
perpetuity of all present and future rights to this software under copyright
|
||||||
|
law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||||
|
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
137
pwd.c.v
Normal file
137
pwd.c.v
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
@[has_globals]
|
||||||
|
module pwd
|
||||||
|
|
||||||
|
import sync
|
||||||
|
|
||||||
|
$if windows {
|
||||||
|
$compile_error('pwd: MS Windows is not supported')
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
__global pwd_mutex &sync.Mutex
|
||||||
|
|
||||||
|
fn init() {
|
||||||
|
pwd_mutex = sync.new_mutex()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cleanup() {
|
||||||
|
pwd_mutex.destroy()
|
||||||
|
unsafe { free(pwd_mutex) }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C.passwd {
|
||||||
|
pw_name &char
|
||||||
|
pw_passwd &char
|
||||||
|
pw_uid i32
|
||||||
|
pw_gid i32
|
||||||
|
pw_gecos &char
|
||||||
|
pw_dir &char
|
||||||
|
pw_shell &char
|
||||||
|
}
|
||||||
|
|
||||||
|
fn C.getpwuid(i32) &C.passwd
|
||||||
|
fn C.getpwnam(&char) &C.passwd
|
||||||
|
fn C.setpwent()
|
||||||
|
fn C.endpwent()
|
||||||
|
fn C.getpwent() &C.passwd
|
||||||
|
|
||||||
|
pub struct Passwd {
|
||||||
|
pub:
|
||||||
|
name string // username
|
||||||
|
passwd string // user password, usually set to 'x'
|
||||||
|
uid int // used ID
|
||||||
|
gid int // group ID
|
||||||
|
gecos string // user information
|
||||||
|
dir string // home directory
|
||||||
|
shell string // shell program
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_passwd(pw &C.passwd) Passwd {
|
||||||
|
return unsafe {
|
||||||
|
Passwd{
|
||||||
|
name: cstring_to_vstring(pw.pw_name)
|
||||||
|
passwd: cstring_to_vstring(pw.pw_passwd)
|
||||||
|
uid: int(pw.pw_uid)
|
||||||
|
gid: int(pw.pw_gid)
|
||||||
|
gecos: cstring_to_vstring(pw.pw_gecos)
|
||||||
|
dir: cstring_to_vstring(pw.pw_dir)
|
||||||
|
shell: cstring_to_vstring(pw.pw_shell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_error(name string, uid int) IError {
|
||||||
|
err := C.errno
|
||||||
|
if err !in [4, 5, 12, 23, 24, 34] {
|
||||||
|
// Error is not EINTR, EIO, ENOMEM, ENFILE, EMFILE or ERANGE
|
||||||
|
return EntryNotFoundError{
|
||||||
|
name: name
|
||||||
|
uid: uid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error_with_code(c_error_number_str(err), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_by_uid returns the passwd database entry by user ID.
|
||||||
|
// If the entry is not found, the EntryNotFoundError error will be returned.
|
||||||
|
pub fn get_by_uid(uid int) !Passwd {
|
||||||
|
pwd_mutex.lock()
|
||||||
|
defer {
|
||||||
|
pwd_mutex.unlock()
|
||||||
|
}
|
||||||
|
pw := C.getpwuid(uid)
|
||||||
|
if isnil(pw) {
|
||||||
|
return make_error('', uid)
|
||||||
|
}
|
||||||
|
return make_passwd(pw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_by_uid returns the passwd database entry by user name.
|
||||||
|
// If the entry is not found, the EntryNotFoundError error will be returned.
|
||||||
|
pub fn get_by_name(name string) !Passwd {
|
||||||
|
pwd_mutex.lock()
|
||||||
|
defer {
|
||||||
|
pwd_mutex.unlock()
|
||||||
|
}
|
||||||
|
pw := C.getpwnam(&char(name.str))
|
||||||
|
if isnil(pw) {
|
||||||
|
return make_error(name, -1)
|
||||||
|
}
|
||||||
|
return make_passwd(pw)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_all returns all entries from passwd database in arbitrary order.
|
||||||
|
pub fn get_all() []Passwd {
|
||||||
|
mut pwds := []Passwd{}
|
||||||
|
pwd_mutex.lock()
|
||||||
|
C.setpwent()
|
||||||
|
defer {
|
||||||
|
C.endpwent()
|
||||||
|
pwd_mutex.unlock()
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
pw := C.getpwent()
|
||||||
|
if isnil(pw) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pwds << make_passwd(pw)
|
||||||
|
}
|
||||||
|
return pwds
|
||||||
|
}
|
||||||
|
|
||||||
|
// EntryNotFoundError designates that an entry with the specified UID or name was not found.
|
||||||
|
pub struct EntryNotFoundError {
|
||||||
|
Error
|
||||||
|
name string
|
||||||
|
uid int
|
||||||
|
}
|
||||||
|
|
||||||
|
// msg returns the string representation of EntryNotFoundError error.
|
||||||
|
pub fn (e EntryNotFoundError) msg() string {
|
||||||
|
if e.name != '' {
|
||||||
|
return "no passwd entry found by username '${e.name}'"
|
||||||
|
}
|
||||||
|
return 'no passwd entry found by user ID ${e.uid}'
|
||||||
|
}
|
||||||
17
pwd_test.v
Normal file
17
pwd_test.v
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// vtest build: !windows
|
||||||
|
import pwd
|
||||||
|
|
||||||
|
fn test_get_by_uid() {
|
||||||
|
pw := pwd.get_by_uid(0)!
|
||||||
|
assert pw.name == 'root'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_get_by_name() {
|
||||||
|
pw := pwd.get_by_name('root')!
|
||||||
|
assert pw.uid == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_get_all() {
|
||||||
|
pws := pwd.get_all()
|
||||||
|
assert pws.len > 0
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user