Commit c0094288 authored by PotatoGim's avatar PotatoGim
Browse files

temp commit


Signed-off-by: PotatoGim's avatarJihyeon Gim <potatogim@potatogim.net>
parent 1874755c
No related merge requests found
Showing with 1207 additions and 0 deletions
+1207 -0
aio_read.c 0 → 100644
#include <aio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define SIZE_TO_READ 1000
int main(int argc, const char *argv[]) {
printf("Hello World\n");
int fd = open(argv[1], O_RDONLY, 0);
if (fd == -1) {
printf("Unable to open file !\n");
return 1;
}
// create a buffer
char *buffer = (char *)calloc(SIZE_TO_READ, 1);
// create a control block structure
struct aiocb cb;
// init the call back
memset(&cb, 0, sizeof(struct aiocb));
cb.aio_nbytes = SIZE_TO_READ;
cb.aio_fildes = fd;
cb.aio_offset = 0;
cb.aio_buf = buffer;
// it'll impliclitly create a new thread to read and jump immediately into the
// next code without waiting the return
if (aio_read(&cb) == -1) {
printf("Unable to create the request!\n");
close(fd);
}
// do_anything_we_want_without_waiting
printf("Request enqueued!\n");
// wait until the request has finished (to check if it is done)
while (aio_error(&cb) == EINPROGRESS) {
printf("Working...: %s\n", (char *)cb.aio_buf);
}
// success ?
int numBytes = aio_return(&cb);
if (numBytes != -1) {
printf("Success!\n");
}
return 0;
}
File added
module custom_generics
go 1.20
package main
/*
* Simple Go custom generic uses
*/
// func ZeroOf[T any]() T {
// var x T
// return x
// }
// func ZeroFor[T any](_ T) T {
// var x T
// return x
// }
// func Zero[T any](p *T) {
// var x T
// *p = x
// }
/*
* A slightly different implementation
*/
func ZeroOf[T any]() T {
var x T
return x
}
func ZeroFor[T any](_ T) T {
return ZeroOf[T]()
}
func Zero[T any](p *T) {
*p = ZeroFor(*p)
}
func main() {
var x = 123
Zero(&x)
println(x) // 0
}
/*
* Simple Getter/Setter implementation
*/
type Property[T any] struct {
v T
}
func (p *Property[T]) Get() T {
return p.v
}
func (p *Property[T]) Set(x T) {
p.v = x
}
type Book struct {
Title Property[string]
Pages Property[int]
}
module inherit
go 1.19
require github.com/davecgh/go-spew v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
File added
package main
import (
"fmt"
)
type Parent struct {
A string
}
func NewParent() Parent {
return Parent{
A: "Parent",
}
}
func NewParentWithPointer() *Parent {
p := NewParent()
return &p
}
func (p *Parent) Say1() {
fmt.Printf("Parent\n")
}
type Child struct {
Parent
B string
}
func NewChild() Child {
return Child{
Parent: NewParent(),
B: "Child",
}
}
func (c *Child) Say2() {
fmt.Printf("Child\n")
}
func main() {
c := NewChild()
c.Say1()
c.Say2()
}
This diff is collapsed.
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Data::Dumper;
use Scalar::Util qw(looks_like_number);
$Data::Dumper::Sortkeys = 1;
my @sorters;
my @conds = (
{
property => 'name',
direction => 'ASC',
},
{
property => 'uid',
direction => 'DESC',
},
);
my @data;
for (my $i = 0; $i < 5; $i++)
{
push(
@data,
{
name => sprintf('user%02d', int(rand(10))),
uid => int(rand(1000)),
},
);
}
foreach my $cond (@conds)
{
my $prop = $cond->{property};
my $dirc = $cond->{direction};
push(
@sorters,
sub
{
if (looks_like_number($a->{$prop})
&& looks_like_number($b->{$prop}))
{
return $dirc eq 'ASC'
? $a->{$prop} <=> $b->{$prop}
: $b->{$prop} <=> $a->{$prop};
}
else
{
return $dirc eq 'ASC'
? $a->{$prop} cmp $b->{$prop}
: $b->{$prop} cmp $a->{$prop};
}
}
);
}
print Dumper(\@data);
@data = sort {
foreach my $sorter (@sorters)
{
my $rv = $sorter->($a, $b);
if ($rv == 0)
{
next;
}
return $rv;
}
} @data;
print Dumper(\@data);
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
# https://stackoverflow.com/questions/45631519/how-to-normalize-a-path-in-perl-without-checking-the-filesystem
my %solutions = (
denilson_answer => sub {
# This is the only solution that passes all the tests listed at the end of this file.
# https://stackoverflow.com/a/45635706
require File::Spec;
my $path = shift;
# canonpath does string manipulation, but does not remove "..".
my $ret = File::Spec->canonpath($path);
# Let's remove ".." by using a regex.
while ($ret =~ s{
(^|/) # Either the beginning of the string, or a slash, save as $1
( # Followed by one of these:
[^/]| # * Any one character (except slash, obviously)
[^./][^/]| # * Two characters where
[^/][^./]| # they are not ".."
[^/][^/][^/]+ # * Three or more characters
) # Followed by:
/\.\./ # "/", followed by "../"
}{$1}x
) {
# Repeat this substitution until not possible anymore.
}
# Re-adding the trailing slash, if needed.
if ($path =~ m!/$! && $ret !~ m!/$!) {
$ret .= '/';
}
return $ret;
},
file_spec_canonpath => sub {
require File::Spec;
my $path = shift;
my $ret = File::Spec->canonpath($path);
if ($path =~ m!^/! && $ret !~ m!^/!) { $ret = '/' . $ret; }
if ($path =~ m!/$! && $ret !~ m!/$!) { $ret .= '/'; }
return $ret;
},
matt_answer_path_tiny => sub {
# https://stackoverflow.com/a/45640854
require Path::Tiny;
my $path = shift;
if ($path eq '') {
# Path::Tiny paths require defined, positive-length parts
return $path;
}
my $ret = '' . Path::Tiny::path($path);
if ($path =~ m!^/! && $ret !~ m!^/!) { $ret = '/' . $ret; }
if ($path =~ m!/$! && $ret !~ m!/$!) { $ret .= '/'; }
return $ret;
},
tom_answer => sub {
# https://stackoverflow.com/a/45631808
my $path = shift;
my @c= reverse split m@/@, $path;
my @c_new;
while (@c) {
my $component= shift @c;
next unless length($component);
if ($component eq ".") { next; }
if ($component eq "..") { shift @c; next }
push @c_new, $component;
}
my $ret = join("/", reverse @c_new);
if ($path =~ m!^/! && $ret !~ m!^/!) { $ret = '/' . $ret; }
if ($path =~ m!/$! && $ret !~ m!/$!) { $ret .= '/'; }
return $ret;
},
georg_answer => sub {
# https://stackoverflow.com/a/70081898
my $path = shift;
my $absolute = $path =~ m!^/!;
my @c = reverse split m@/@, $path;
my @c_new;
while (@c) {
my $component= shift @c;
next unless length($component);
if ($component eq ".") { next; }
if ($component eq "..") {
my $i=0;
while ($c[$i] && $c[$i] =~ m/^\.{1,2}$/) {
$i++
}
if ($i > $#c) {
push @c_new, $component unless $absolute;
} else {
splice(@c, $i, 1);
}
next
}
push @c_new, $component;
}
my $ret = join("/", reverse @c_new);
if ($path =~ m!^/! && $ret !~ m!^/!) { $ret = '/' . $ret; }
if ($path =~ m!/$! && $ret !~ m!/$!) { $ret .= '/'; }
return $ret;
},
j_l_answer => sub {
# https://stackoverflow.com/a/76568741/124946
require File::Spec::Win32;
my $path = shift;
$path =~ s[\\][\0]g; # Converts backslashes to null bytes.
$path = File::Spec::Win32->canonpath($path);
$path =~ s[\\][/]g; # Converts \ to / characters.
$path =~ s[\0][\\]g; # Converts null bytes back to backslashes.
# $path is now set to: /b/c/d
return $path;
},
j_l_answer_modified => sub {
# https://stackoverflow.com/a/76568741/124946
require File::Spec::Win32;
my $path = shift;
my $ret = $path;
$ret =~ s[\\][\0]g; # Converts backslashes to null bytes.
$ret = File::Spec::Win32->canonpath($ret);
$ret =~ s[\\][/]g; # Converts \ to / characters.
$ret =~ s[\0][\\]g; # Converts null bytes back to backslashes.
# Re-adding the trailing slash, if needed.
if ($path =~ m!/$! && $ret !~ m!/$!) {
$ret .= '/';
}
return $ret;
},
);
# Which one you want to test?
my $func;
my @options = sort keys %solutions;
my $selected_index;
if (defined $ARGV[0] && $options[$ARGV[0]]) {
$selected_index = 0 + $ARGV[0];
}
if (!defined $selected_index) {
while (1) {
print "Which solution do you want to test?\n";
for my $i (0..$#options) {
print " $i $options[$i]\n";
}
my $input = <STDIN>;
my $number = 0 + $input;
if ($options[$number]) {
$selected_index = $number;
last;
}
}
}
print "Testing $options[$selected_index]\n";
$func = $solutions{$options[$selected_index]};
# To quickly format these lines in vim: :'<,'>Tabularize /), \|,/l0
is( $func->('' ), '' ,'empty');
is( $func->('/' ), '/' ,'root');
is( $func->('foo' ), 'foo' ,'simple');
is( $func->('foo/' ), 'foo/' ,'simple dir');
is( $func->('/foo' ), '/foo' ,'root simple');
is( $func->('/foo/'), '/foo/','root dir');
is( $func->('foo/bar' ), 'foo/bar' ,'two components');
is( $func->('foo/bar/' ), 'foo/bar/' ,'two components');
is( $func->('/foo/bar' ), '/foo/bar' ,'two components');
is( $func->('/foo/bar/'), '/foo/bar/','two components');
is( $func->('foo//bar' ), 'foo/bar' ,'double slash');
is( $func->('foo//bar/' ), 'foo/bar/' ,'double slash');
is( $func->('/foo//bar' ), '/foo/bar' ,'double slash');
is( $func->('/foo//bar/' ), '/foo/bar/','double slash');
is( $func->('foo///bar' ), 'foo/bar' ,'triple slash');
is( $func->('foo///bar/' ), 'foo/bar/' ,'triple slash');
is( $func->('/foo///bar' ), '/foo/bar' ,'triple slash');
is( $func->('/foo///bar/' ), '/foo/bar/','triple slash');
is( $func->('foo////bar' ), 'foo/bar' ,'four slashes');
is( $func->('foo////bar/' ), 'foo/bar/' ,'four slashes');
is( $func->('/foo////bar' ), '/foo/bar' ,'four slashes');
is( $func->('/foo////bar/'), '/foo/bar/','four slashes');
is( $func->('./foo' ), 'foo' ,'leading dot');
is( $func->('./foo/' ), 'foo/' ,'leading dot');
is( $func->('/./foo' ), '/foo' ,'leading dot');
is( $func->('/./foo/'), '/foo/','leading dot');
is( $func->('foo/./bar' ), 'foo/bar' ,'dot');
is( $func->('foo/./bar/' ), 'foo/bar/' ,'dot');
is( $func->('/foo/./bar' ), '/foo/bar' ,'dot');
is( $func->('/foo/./bar/' ), '/foo/bar/','dot');
is( $func->('foo/././bar' ), 'foo/bar' ,'dot dot');
is( $func->('foo/././bar/' ), 'foo/bar/' ,'dot dot');
is( $func->('/foo/././bar' ), '/foo/bar' ,'dot dot');
is( $func->('/foo/././bar/' ), '/foo/bar/','dot dot');
is( $func->('foo/./././bar' ), 'foo/bar' ,'dot dot dot');
is( $func->('foo/./././bar/' ), 'foo/bar/' ,'dot dot dot');
is( $func->('/foo/./././bar' ), '/foo/bar' ,'dot dot dot');
is( $func->('/foo/./././bar/'), '/foo/bar/','dot dot dot');
is( $func->('a/b/c/d' ), 'a/b/c/d' ,'four components');
is( $func->('a/b/c/d/' ), 'a/b/c/d/' ,'four components');
is( $func->('/a/b/c/d' ), '/a/b/c/d' ,'four components');
is( $func->('/a/b/c/d/'), '/a/b/c/d/','four components');
is( $func->('a/b/../c/d' ), 'a/c/d' ,'parent');
is( $func->('a/b/../c/d/' ), 'a/c/d/' ,'parent');
is( $func->('/a/b/../c/d' ), '/a/c/d' ,'parent');
is( $func->('/a/b/../c/d/'), '/a/c/d/','parent');
is( $func->('a/b/../../c/d' ), 'c/d' ,'parent parent');
is( $func->('a/b/../../c/d/' ), 'c/d/' ,'parent parent');
is( $func->('/a/b/../../c/d' ), '/c/d' ,'parent parent');
is( $func->('/a/b/../../c/d/'), '/c/d/','parent parent');
is( $func->('a/../b/../c/../d' ), 'd' ,'several parents');
is( $func->('a/../b/../c/../d/' ), 'd/' ,'several parents');
is( $func->('/a/../b/../c/../d' ), '/d' ,'several parents');
is( $func->('/a/../b/../c/../d/'), '/d/','several parents');
is( $func->('/../a/b' ), '/a/b' ,'root parent');
is( $func->('/../a/b/' ), '/a/b/','root parent');
is( $func->('/../../a/b' ), '/a/b' ,'root parent parent');
is( $func->('/../../a/b/'), '/a/b/','root parent parent');
is( $func->('../foo' ), '../foo' ,'leading parent');
is( $func->('../foo/' ), '../foo/' ,'leading parent');
is( $func->('../../foo' ), '../../foo' ,'leading parent parent');
is( $func->('../../foo/' ), '../../foo/','leading parent parent');
is( $func->('a/../../foo' ), '../foo' ,'too many parents');
is( $func->('a/../../foo/'), '../foo/' ,'too many parents');
done_testing();
1;
require 'puppet'
require 'facter/util/plist'
require 'stringio'
require 'base64'
def convert_xml_to_binary(plist_data)
# This method will accept a hash that has been returned from Plist::parse_xml
# and convert it to a binary plist (string value).
Puppet.debug('Converting XML plist to binary')
Puppet.debug('Executing: \'plutil -convert binary1 -o - -\'')
IO.popen('plutil -convert binary1 -o - -', mode='r+') do |io|
io.write Plist::Emit.dump(plist_data)
io.close_write
@converted_plist = io.read
end
@converted_plist
end
def convert_binary_to_xml(plist_data)
# This method will accept a binary plist (as a string) and convert it to a
# hash via Plist::parse_xml.
Puppet.debug('Converting binary plist to XML')
Puppet.debug('Executing: \'plutil -convert xml1 -o - -\'')
IO.popen('plutil -convert xml1 -o - -', mode='r+') do |io|
io.write plist_data
io.close_write
@converted_plist = io.read
end
Puppet.debug('Converting XML values to a hash.')
@plist_hash = Plist::parse_xml(@converted_plist)
@plist_hash
end
## Setting the Password with dsimport
@resource = 'jeff'
value = "7ea7d592131f57b2c8f8bdbcec8d9df12128a386393a4f00c7619bac2622a44d451419d11da512d5915ab98e39718ac94083fe2efd6bf710a54d477f8ff735b12587192d"
binary_password_value = Base64.decode64([[value].pack("H*")].pack("m").strip)
archive_hash = Hash.new
archive_hash = { 'SALTED-SHA512' => StringIO.new }
archive_hash['SALTED-SHA512'].string = binary_password_value
binary_archive_hash = convert_xml_to_binary(archive_hash)
tmpdir = Dir.mktmpdir
password_file = File.join(tmpdir, 'binary_password')
cached_source = File.join(tmpdir, 'dsimportfile')
#junk = Marshal.dump(binary_archive_hash)
File.open(password_file, 'w') { |file| file.write(binary_archive_hash) }
File.open(cached_source, 'w') { |file| file.write("0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName externalbinary:dsAttrTypeStandard:ShadowHashData \n#{@resource}:#{password_file}") }
`/usr/bin/dsimport #{cached_source} /Local/Default O`
## Get the password from disk using dscl
shadow_hash_data = Plist.parse_xml(`/usr/bin/dscl -plist . read /Users/jeff ShadowHashData`)
binary_plist = Array(shadow_hash_data['dsAttrTypeNative:ShadowHashData'][0].delete(' ')).pack('H*')
embedded_binary_plist = convert_binary_to_xml(binary_plist)
key_from_disk = embedded_binary_plist['SALTED-SHA512'].string.unpack("H*")[0]
## Back out the data we calculated in the first block
backed_out_plist = convert_binary_to_xml(binary_archive_hash)
key_from_backup = backed_out_plist['SALTED-SHA512'].string.unpack("H*")[0]
## They don't match
puts 'THEY MATCH' if key_from_backup == key_from_disk
## Read the data we JUST wrote to disk and compare the keys:
## Read from disk
data_from_disk = File.open(password_file, "rb").read
converted_plist = convert_binary_to_xml(data_from_disk)
key_from_file = converted_plist['SALTED-SHA512'].string.unpack("H*")[0]
## Yes, this is a match
puts "Sure are!" if key_from_file == value
## Okay, so let's try just modifying the user's plist
users_plist = Plist::parse_xml(`plutil -convert xml1 -o /dev/stdout /var/db/dslocal/nodes/Default/users/jeff.plist`)
password_hash_plist = users_plist['ShadowHashData'][0].string
converted_hash_plist = convert_binary_to_xml(password_hash_plist)
#converted_hash_plist['SALTED-SHA512'].string = value.unpack('a2'*(value.size/2)).collect { |i| i.hex.chr }.join
converted_hash_plist['SALTED-SHA512'].string = Base64.decode64([[value].pack("H*")].pack("m").strip)
changed_plist = convert_xml_to_binary(converted_hash_plist)
users_plist['ShadowHashData'][0].string = changed_plist
Plist::Emit.save_plist(users_plist, '/var/db/dslocal/nodes/Default/users/jeff.plist')
`plutil -convert binary1 /var/db/dslocal/nodes/Default/users/jeff.plist`
## Great, now read directly from the plist
get_plist = Plist::parse_xml(`plutil -convert xml1 -o /dev/stdout /var/db/dslocal/nodes/Default/users/jeff.plist`)
get_password_hash_plist = get_plist['ShadowHashData'][0].string
get_converted_hash_plist = convert_binary_to_xml(get_password_hash_plist)
get_password_hash = get_converted_hash_plist['SALTED-SHA512'].string.unpack("H*")[0]
## Do they match? Yes they do.
puts "THEY MATCH" if value == get_password_hash
## Now, let's read from DSCL again...
shadow_hash_data = Plist.parse_xml(`/usr/bin/dscl -plist . read /Users/jeff ShadowHashData`)
binary_plist = Array(shadow_hash_data['dsAttrTypeNative:ShadowHashData'][0].delete(' ')).pack('H*')
embedded_binary_plist = convert_binary_to_xml(binary_plist)
key_from_disk = embedded_binary_plist['SALTED-SHA512'].string.unpack("H*")[0]
## Do they match? Yes they do.
puts "THEY MATCH" if value == key_from_disk
## In summary, we're setting incorrectly with dsimport
## Reading from dscl the correct value:
#62706c69 73743030 d101025d 53414c54 45442d53 48413531 324f1044 7ea7d592 131f57b2 c8f8bdbc ec8d9df1 2128a386 393a4f00 c7619bac 2622a44d 451419d1 #1da512d5 915ab98e 39718ac9 4083fe2e fd6bf710 a54d477f 8ff735b1 2587192d 080b1900 00000000 00010100 00000000 00000300 00000000 00000000 00000000 000060
## Reading from dscl with the INCORRECT value:
#62706c69 73743030 d101025d 53414c54 45442d53 48413531 324f1044 4ebb58ad e6e87d16 2a410d01 685acbe0 2a8ba79a 4791327b ca153a67 86578057 6df98883 #37b33eca ede269f5 77c81d6b e96456df cf9f34d6 a6f1d919 03f46052 0e878346 080b1900 00000000 00010100 00000000 00000300 00000000 00000000 00000000 000060
delete this gist
Comments are parsed with GitHub Flavored Markdown
Write
File added
fn main() {
println!("Hello, world!");
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment