|
-
May 08, 2024, 09:00:24 pm
- Welcome, Guest
News:Official site launch very soon, hurrah!
Show Posts
This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.
Messages - Dakusan
1
« on: May 02, 2024, 10:33:44 pm »
After years of saying I’d do it, I'm finally moving my ecosystem from Windows to Linux. After some experimenting and soul searching, I've decided to go with Linux Mint, as it's not exactly Ubuntu with their atrociously horrible decisions, but it provides stability, ease of setup, and a similar enough interface to Windows so as to not lower my productivity. Getting all of my legacy hardware working, including my 6-monitor setup, was mostly painless, but my beloved Babyface Pro (external professional audio mixer hardware) has been absolute hell to get working. It only natively supports Windows, OSX, and iOS for the “PC” (USB audio passthrough) mode, and the CC mode (class compliant) does not offer my custom waveform transforms. So, my only real option was to use the other analog input interfaces on the Babyface (XLR, SPDIF, or quarter inch audio). The first hurdle was the power. Normally the device is powered through USB, however if I was going to be using the other audio inputs, I didn't want to leave the USB plugged in all the time, and the Babyface doesn't come with a power adapter. Fortunately, I had a 12V 1A+ power adapter in my big box of random power adapters. The second hurdle was when I discovered that the Babyface does not store the mixer settings when it's powered off. So, every time it gets powered on, it needs to be hooked to another (Windows) machine that can push the mixer settings to it. This also isn't too big a deal as I keep it on a UPS so it generally won't lose power, and if it does, I can use a VM to push the settings. The next problem was deciding what interface to go through. I was really hoping to use SPDIF/optical since it is a digital signal that does not suffer from interference and degradation, but all the SPDIF interfaces I tried (4 in total) all sounded like garbage. I guess the SPDIF interface on the Babyface is a piece of Junk, which was very disheartening. My only remaining option was using the analog inputs. I decided to use a mini (3.5mm; 1/8") stereo to quarter inch (6.35mm) mono splitter cord to run into “IN 3/4” and this worked perfectly. However, if the USB interface is plugged in at the same time then this actually creates very audible line noise on the analog inputs within the Babyface itself! This is a horrible design flaw of the device that I was shocked to run into. Fortunately, as mentioned in step 1, I already planned on having the USB cord unplugged, so not a deal breaker. I first tried the headphone and line out jacks on my motherboard, but the audio quality was only at about 90%. I next tried the line out on my Creative Sound Blaster Audigy from 2014 and the audio was at about 95% quality. It also felt like a cardinal sin to plug in a PCIE 1.0 1x device (0.250 GB/s) into a PCIE 5.0 16x slot (63 GB/s) - lol. So, I bought a Sound Blaster Play 3! USB to mini audio adapter and the audio was perfect! I finally had my setup figured out. As a fun note, I went to an audiologist a few days ago to have my hearing tested, and the waveform I had devised (through brute force testing) that I had been using through the Babyface for the last 7 years was the exact inverse of the results on the hearing loss frequency chart.
2
« on: April 14, 2024, 11:11:15 pm »
The nulltypes system has been overhauled so all null types are under a generic type named NullType in the top level package. For example, instead of using nulltypes.NullUint8 you would now use NullType[uint8]. This also really helped clean up the null types code. This is a version breaking change, hence the minor version number update. Other minor changes: - Readme file and package information has been updated with the following changes:
- The type support section has been redone for clarity
- The structs in the code examples have had the members labeled to explain their used supported type
- Marshled JSON strings are now properly json escaped
- Added bypass for my RawBytes bug fix, now that it has been fixed in go v1.23
- Removed test case that is no longer compatible with go 1.21+
3
« on: March 23, 2024, 08:44:56 am »
I made a pretty massive overhaul of my resume. Both the PDF and the copy on this site’s resume section have been updated.
4
« on: March 16, 2024, 03:08:08 am »
GoFasterSQL is a tool designed to enhance the efficiency and simplicity of scanning SQL rows into structures in Go[lang]. While this project was first released in December of 2023 on github and has already had 7 releases there, I’ve finally gotten around to adding it here. I don’t anticipate there being many more releases any time soon as the project is feature complete.
5
« on: March 16, 2024, 02:50:14 am »
Description: GoFasterSQL is a tool designed to enhance the efficiency and simplicity of scanning SQL rows into structures. Information: The flaw in the native library scanning process is its repetitive and time-consuming type determination for each row scan. It must match each field’s type with its native counterpart before converting the data string (byte array). Furthermore, the requirement to specify each individual field for scanning is tedious. GoFasterSQL instead precalculates string-to-type conversions for each field, utilizing pointers to dedicated conversion functions. This approach eliminates the need for type lookups during scanning, vastly improving performance. The library offers a 2 to 2.5 times speed increase compared to native scan methods (5*+ vs sqlx), a boost that varies with the number of items in each scan. Moreover, its automatic structure determination feature is a significant time-saver during coding. See the github page for full documentation. Languages: MySQL, GoLang
6
« on: March 16, 2024, 02:33:50 am »
Gol10n is a highly space and memory optimized l10n (localization) library for Go (GoLang) pronounced “Goal Ten”. While this project was first released in December of 2023 on github and has already had 5 releases there, I’ve finally gotten around to adding it here. I don’t anticipate there being many more releases any time soon as the project is feature complete.
7
« on: March 16, 2024, 02:00:13 am »
Description: This is a highly space and memory optimized l10n (localization) library for Go (GoLang) pronounced “Goal Ten”. Information: Translation strings are held, per language, in text files (either YAML or JSON), and compile into .gtr or .gtr.gz (gzip compressed) files. Translations can be referenced in Go code either by an index, or a namespace and translation ID. Referencing by index is the fastest, most efficient, and what this library was built for. Indexes are stored as constants in generated Go dictionary files by namespace, and are also held in the dictionary. See the github page for full documentation. Languages: GoLang
8
« on: March 16, 2024, 12:15:03 am »
I finally got around to bringing this ~20 year old website somewhat up to date. - Hid ~10 old projects that noone would care about or are silly to download an executable for when a website could just as easily handle it.
- Redid the projects page to list projects by type, cleaned up the layout, and removed the silly sorting and smart table stuff.
- Changed background to a solid color instead of 1px stripes, which didn’t work well on mobile.
- Fixed layout issues with dynamic section borders
- Fixed other layout issues with CSS that are now compatible with modern browsers
- Added mobile compatibility tags and standardized to webfonts for mobile compatibility
- Fixed anything that used adobe/macromedia flash
- Removed IE6 compatibility layer
- Updated copyright and license information
- Got rid of the silly glossary functionality
- Made sure all links now use https instead of http
- Added my email address to the contact page
- Overhauled the search page
9
« on: February 16, 2024, 01:03:32 am »
Go has been around for quite a while now and has had a lot of time to grow and mature, and it is really quite a lovely language. Watching it develop since its inception has been a delight. Its native concurrency is best in the industry, it is designed for things to be super-clean and standardized, and it compiles really fast. The support for it in IntelliJ/GoLand is top-notch and makes it really a blast to work in. There are of course a lot of design decisions in the language that could be debated, like how setting a variable has to be a top level statement that cannot be embedded in other statements, how there is no “real” class based system, and how their specific name casing conventions are actually built into the language and enforced. However, I understand the reason for all of these decisions and feel that the designers of the language were justified in the decisions they made for the reasons they give. There are at least 6 problems I’ve run into a lot recently though that I feel could be better. I would love to jump into the source of the language and see about making these fixes myself, but the GoLang team has a history of completely ignoring outsiders, and it would be highly unlikely that they would accept anything I submitted, especially since a number of these things would require very long and complicated proposals to even start looking at. Go may be an open source language, but it is not open development. These first 3 would be additions to the language that would not break anything, which is in line with their promise of never breaking anything. 1) Interface with constraints elements cannot be used as variable types. Example: type intish interface{ int64 | uint64 } func adder[T intish](val T) T { return val + 1 } //This is allowed var val intish //Error: cannot use type intish outside a type constraint: interface contains type constraints
IntelliJ inspection Error: Interface includes constraint elements '...', can only be used in type parameters It wouldn’t be a big change for the compiler and runtime to be able to enforce these types of constraints when typecasting and I really wish the language had this. This is the type of thing TypeScript does beautifully since it is actually part of its native design and functioning. 2) Member functions (methods with receivers) cannot have generics type foobar int func (*foo) bar[T any](val T) {} //Method cannot have type parameters
3) []generic cannot be typecast to []anyThere is no real reason that an array containing interfaces shouldn’t be convertable via typecast to another array of interface types as long as they are compatible. type testAny any startVar := make([]testAny, 3) endVar := []any(startVar) //cannot convert startVar (variable of type []testAny) to type []any
This next one is an unfortunate consequence of the language design and would not be easily fixable. 4) Import cycle not allowedThis means there cannot be circular dependencies. If package A includes package B, then package B cannot include package A. This often wasn’t a problem with languages like C since the headers were independent of the implementations, but because packages in Go do not have headers, and their package types cannot be used as method receivers in other packages, this one is just not possible. And it can be quite limiting.
This next one is a bug in either the language or the documentation, and I consider it to be a security problem, but the go team does not seem to care about it. See https://github.com/golang/go/issues/65201 [Edit on 2024-04-10] Oh wow! they fixed it! 5) sql.RawBytes modifies the current buffers instead of setting new buffers like the documentation says.All the documentation says about RawBytes is “RawBytes is a byte slice that holds a reference to memory owned by the database itself. After a Rows.Scan into a RawBytes, the slice is only valid until the next call to Rows.Next, Rows.Scan, or Rows.Close.” If the value you are reading is a []byte/string then reading into a RawBytes works as expected. However, if it is anything else, like an int, it reads into the buffer that RawBytes already holds. This can lead to buffer injections and other really nasty bugs. For example: db.Exec(`CREATE TEMPORARY TABLE goTest (i int NOT NULL, str varchar(10)) ENGINE=MEMORY`) db.Exec(`INSERT INTO goTest VALUES (?, ?)`, 6, "foobar") var scanIn sql.RawBytes rows, _ := db.Query(`SELECT str FROM goTest WHERE i=?`, 6) rows.Next() rows.Scan(&scanIn) //Do something with scanIn rows.Close() rows, _ = db.Query(`SELECT i FROM goTest WHERE i=?`, 6) rows.Next() rows.Scan(&scanIn) //This corrupts the internal sql driver buffer since it reads an int into the pointer we received earlier
This final one has been an annoyance of mine since day 1 of working with Go, and it still annoys the hell out of me. There could be ways to fix it without breaking things, but I cannot think of any truly elegant solutions. 6) Short variable declaration can’t handle setting both new and already existing variablesThis is the most common pattern you’ll see in Go by far: var data string if _data, err := someFunc(); err != nil { fmt.Println(err) } else { data = _data }
You can either do it this way, or also declare err in the outer scope, thereby polluting the scope with unneeded variables. There is no way to set both the temporary error variable and also set the outer data variable in 1 line. One non-breaking hack would be to add a symbol before variables you wanted to set in the outer scope. Example: var data string if +data, err := someFunc(); err != nil { fmt.Println(err) }
10
« on: October 09, 2021, 12:08:35 am »
The following is a tutorial on mounting a dd image of a TrueCrypt system-level-encrypted volume. This tutorial was tested and written against Ubuntu 16.04.2 LTS. Trying to mount your loopback device with losetup or mount doesn’t quite work. If you tried, you’d get an error like the following: No such file or directory: /sys/block/loop2/loop2p2/start VeraCrypt::File::Open:276
Instead, use sudo kpartx -va IMAGE_FILENAME.This will give you something like the following: add map loop2p1 (253:0): 0 204800 linear 7:2 2048 add map loop2p2 (253:1): 0 976564224 linear 7:2 206848
This shows you the partitions in the image and which loopback devices they are mounted to. In my case, loop2 and loop2p2, which I will continue using for the rest of this tutorial. So this mounts the following: - /dev/loop2: The primary loopback device
- /dev/mapper/loop2p*: The partition loopback devices (in my case, loop2p1 and loop2p2)
If you attempt to mount loop2p2 with TrueCrypt or VeraCrypt as a system partition, no matter the password, you will get the error “Partition device required”. To fix this we need to get the loop2p2 to show up in /dev and make an edit to the VeraCrypt source code. You can run the following command to see the loopback partition devices and their sizes. This is where I am pulling loop2p2 from. lsblk /dev/loop2 This will give the following: NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT loop2 7:2 0 465.8G 1 loop ├─loop2p2 253:1 0 465.7G 1 part └─loop2p1 253:0 0 100M 1 part
Run the following command to create /dev/loop2p* block devices: sudo partx -a /dev/loop2 Run the following commands to download and compile VeraCrypt: sudo apt-get install git yasm libfuse-dev libwxgtk3.0-dev #yasm requires universe repository git clone https://github.com/veracrypt/VeraCrypt cd VeraCrypt/src nano Platform/Unix/FilesystemPath.cpp #You can use the editor of your choice for this
In Platform/Unix/FilesystemPath.cpp make the following change: After the following 2 lines of code in the FilesystemPath::ToHostDriveOfPartition() function, currently Line 78: #ifdef TC_LINUX path = StringConverter::StripTrailingNumber (StringConverter::ToSingle (Path));
Add the following: string pathStr = StringConverter::ToSingle (path); size_t t = pathStr.find("loop"); if(t != string::npos) path = pathStr.substr (0, pathStr.size() - 1);
Then continue to run the following commands to finish up: make Main/veracrypt -m system,ro,nokernelcrypto -tc /dev/loop2p2 YOUR_MOUNT_LOCATION
VeraCrypt parameter information: - If you don’t include the “nokernelcrypto” option, you will get the following error:
device-mapper: reload ioctl on veracrypt1 failed: Device or resource busy Command failed
- the “ro” is if you want to mount in readonly
- “-tc” means the volume was created in TrueCrypt (not VeraCrypt)
Doing this in Windows is a lot easier. You just need to use a program called Arsenal Image Mounter to mount the drive, and then mount the partition in TrueCrypt (or VeraCrypt).
11
« on: January 19, 2020, 01:11:48 am »
I’ve always thought that the RSA and Diffie–Hellman public key encryption algorithm systems are beautiful in their complex simplicity. While there are countless articles out there explaining how to implement them, I have never really found one that I think describes the math behind then in a simple way, so I thought I’d give a crack at it. Both algorithms are derived from 3 math axioms: - This is called Modular exponentiation (hereby referred to as modexp). In the following, x is a prime numbers and p is an integer less than x.
p^(x ) mod x = p (e.x. 12^(17 ) mod 17 = 12) p^(x-1) mod x = 1 (e.x. 12^(17-1) mod 17 = 1 )
- A further derivation from the above formulas shows that we can combine primes and they work in the same manner. In the following, x and y are prime numbers and p is an integer less than x*y.
p^((x-1)*(y-1) ) mod (x*y) = 1 (e.x. 12^((13-1)*(17-1) ) mod (13*17) = 1 ) Note: This formula is not used in RSA but it helps demonstrate how the formulas from part 1 becomes formula 2b. Due to how modexp works with primes, values of p that are multiples of x or y do not work with 2a. p^((x-1)*(y-1)+1) mod (x*y) = p (e.x. 12^((13-1)*(17-1)+1) mod (13*17) = 12)
- The final axiom is how modexp can be split apart the same way as in algebra where (x^a)^b === x^(a*b). For any integers p, x, y, and m:
(p^(x*y) mod m) === ((p^x mod m)^y mod m)
With these 3 axioms we have everything we need to explain how RSA works. To execute an RSA exchange, encrypted from Bob and decrypted by Alice, the following things are needed.
The variable | Variable name | Who has it | Who uses it | Description |
---|
Prime Numbers 1 and 2 | Prime1, Prime2 | Alice | Alice | Alice will use these to derive variables PubKey, PrivKey, and Modulo. In our examples we use small numbers, but in reality, very large primes will be used, generally of at least 256 bit size. | Public key | PubKey | Alice, Bob | Bob | Alice sends this to Bob so he can encrypt data to her. Bob uses it as an exponent in a modexp. | Private key | PrivKey | Alice | Alice | Alice uses this to decrypt what Bob sends her. Alice uses it as an exponent in a modexp. | Modulo | Modulo | Bob, Alice | Bob, Alice | Alice sends this to Bob. They both use it as a modulo in a modexp | Payload Data | Payload | The data bob starts with and turns into EncryptedPayload. Alice derives Payload back from EncryptedPayload |
Now, let’s start with axiom 2b: Payload^((Prime1-1)*(Prime2-1)+1) mod (Prime1*Prime2) = Payload Let’s change this up so the exponent is just 2 multiplications so we can use axiom 3 on it. We need to find 2 integers to become PubKey and PrivKey such that: PubKey*PrivKey=(Prime1-1)*(Prime2-1)+1 And Modulo is Prime1*Prime2. So we now have: Payload^(PubKey*PrivKey) mod Modulo = Payload Now, using axiom 3, we can turn it into this: (Payload^PubKey mod Modulo)^PrivKey mod Modulo = Payload Now, we can split this up into:Bob calculates and sends to Alice: Payload^PubKey mod Modulo=EncryptedPayloadAlice uses the received EncryptedPayload and performs: EncryptedPayload^PrivKey mod Modulo = PayloadAnd the process is complete! However, there is 1 caveat that I didn’t cover which makes the encryption that what we currently have weak. The calculation of PubKey and PrivKey from Prime1 and Prime2 needs to follow some rather specific complex rules to make the keys strong. Without this, an attacker may be able to figure out Prime1 and Prime2 from the Modulo and PubKey, and could then easily derive PrivKey from it. I generally see the PubKey as 65535, or another power of 2 minus 1.
12
« on: January 10, 2020, 05:23:33 pm »
Tmux is a great alternative to gnu screen. I can’t believe I’ve never posted my custom Tmux config for Cygwin after all the work I put into it years ago. So here it is. Its features include: - Uses ctrl+a, like gnu screen, instead of ctrl+b
- Mouse interaction is enabled
- Tab bar/windows:
- Current tab is highlighted in cyan
- Cycle through tabbed windows with a click on its tab or ctrl+arrowkeys
- Reorder tabbed windows with a drag of its tab or alt+arrowkeys
- ctrl+a,/ to rename a tab on the tab bar
- Create new window with ctrl+a,c
- Panes
- Create split panes with vertical=ctrl+a,| and horizontal=ctrl+a,-
- Move around panes with click or ctrl+shift+arrowkeys
- Resize panes by dragging on the separator bar or use ctrl+shift+alt+arrowkeys
- Panes automatically resize to fit OS window
- Clipboard/highlighting
- Copy text to clipboard by highlighting it. Had to use a minor hack to fix a cygwin selection problem
- Paste from clipboard with right click
- Middle mouse button+drag starts copy mode
- When in copy mode, u runs the selection as a command in a separate window (Instead of “cygstart” for cygwin, use “xdg-open” for linux, or “open” for MacOS X)
- Double click selects word
- Double middle click runs the word under the mouse as a command
- Start the session on the current bash directory
- Escape time is lowered for quicker response to scroll buffer access (ctrl+a,pageup)
To use this, save the file to ~/.tmux.conf #Set current directory setting for cygwin set-environment -g CHERE_INVOKING 1
#Mouse interaction set -g mouse on
#Lower escape timing from 500ms to 50ms for quicker response to scroll-buffer access set -s escape-time 50
#Window always takes up largest possible max size set-window-option -g aggressive-resize
#Highlight active window in tab-bar at bottom in cyan set-window-option -g window-status-current-bg cyan
#Reorder windows in status bar by drag & drop bind-key -n MouseDrag1Status swap-window -t=
#Copy to clipboard on text selection in cygwin. Move cursor position 1 to the right before copy to bypass a bug bind -Tcopy-mode MouseDragEnd1Pane send-keys -X cursor-right\; send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer > /dev/clipboard"
#Paste from clipboard with right click in cygwin bind-key -n MouseDown3Pane run-shell 'tmux set-buffer -b winclip "$(cat /dev/clipboard)"'\; paste-buffer -db winclip
#Middle drag starts copy mode bind -n MouseDrag2Pane copy-mode -M
#When in copy mode, "u" runs the selection as a command in a separate window (Instead of "cygstart" for cygwin, use "xdg-open" for linux, or "open" for MacOS X) bind -Tcopy-mode u send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer | xargs cygstart"
#Double click selects word bind-key -n DoubleClick1Pane copy-mode -M\; send-keys -X select-word
#Double middle click runs the word under the mouse as a command. See description for MouseDown3Pane above bind-key -n DoubleClick2Pane copy-mode -M\; send-keys -X select-word\; send -X copy-selection-and-cancel\; run-shell -b "tmux show-buffer | xargs cygstart"
#Remap prefix to Control+a set -g prefix C-a unbind C-b #bind 'C-a C-a' to type 'C-a' bind C-a send-prefix
#Start in CWD when creating or splitting tabs; move the splitting planes keys to | and - bind '|' split-window -h -c '#{pane_current_path}' # Split panes horizontal bind '-' split-window -v -c '#{pane_current_path}' # Split panes vertically bind c new-window -c '#{pane_current_path}' # Create new window unbind '"' unbind %
#prefix, / -- Renames window, but starts blank bind-key / command-prompt "rename-window '%%'"
#Select next/prev window with Ctrl+(Left|Right) bind-key -n C-Right next-window bind-key -n C-Left previous-window
#Reorder window with Alt+(Left|Right) bind-key -n M-Left swap-window -t -1 bind-key -n M-Right swap-window -t +1
#Switch panes using Ctrl+Shift+arrow bind -n C-S-Left select-pane -L bind -n C-S-Right select-pane -R bind -n C-S-Up select-pane -U bind -n C-S-Down select-pane -D
#Resize panes using Ctrl+Shift+Alt+arrow bind-key -n C-S-M-Up resize-pane -U 1 bind-key -n C-S-M-Down resize-pane -D 1 bind-key -n C-S-M-Left resize-pane -L 1 bind-key -n C-S-M-Right resize-pane -R 1
13
« on: September 24, 2019, 04:59:08 pm »
I recently decided to swap around my hard drives to different SATA slots so my most used hard drives were on the fastest ports. Unfortunately, when I did this, my computer stopped booting to Windows. I never did figure out why my bootable EFI partitions only showed up randomly in BIOS depending on which hard drives were plugged in, but I found a configuration the computer liked and I was able to see the Microsoft Boot EFI partition and EFI boots on my USB keys. The next step was to get the computer actually booting to something I could run commands on. When I try to boot directly to the EFI shell, the resolution is always screwed up and I can only see the top half of what should be visible, so I can’t actually see the command line I am typing too. This actually happens to everything I directly boot to that uses console text. The way around this for me is that I need to boot to the BIOS setup, and from there tell it to boot immediately to the EFI option of my choice when exiting the BIOS. From there, the proper resolution is used and everything is visible. Next, in the EFI shell, you can run map to see all of the available possible mounts. This should automatically run when the EFI shell starts anyways, so you should already have that information. Any detected EFI partition on any bootable device should be given a mapping of “fs#” where # is a number. In my case, it was fs0. So to mount that, I ran mount fs0 x. “x” could be whatever you want, it doesn’t really matter. It’s analogous to a drive letter in windows, and you can make it any string (within reason, I believe anything alphanumeric should be fine). So next you would run x: to switch to that drive. From there, you can run cd EFI\Microsoft\Boot and then bootmgfw.efi to boot to windows. Since I use VeraCrypt system encryption, I had to go to “EFI\VeraCrypt” and run DcsBoot.efi to finally boot into Windows through VeraCrypt. Finally, to get the Windows Boot manager to start with VeraCrypt, run in the Windows command prompt bcdedit /set '{bootmgr}' path \EFI\VeraCrypt\DcsBoot.efi.
14
« on: August 10, 2019, 10:48:07 pm »
I recently tried to install Slackware 4.2 64-bit (Linux) onto a new mini PC I just bought. The new PC only supports UEFI so I had major issues getting the darn setup on the install cd to actually run. I never DID actually get the install cd to boot properly on the system, so I used an alternative. While the slack install usb key was in, I also added and loaded up an ubuntu live cd usb key. The following is what I used to run the slackware setup in Ubuntu. #Login as root #sudo su
#Settings InstallDVDName=SlackDVD #This is whatever you named your slackware usb key
#/mnt will contain the new file system for running the setup cd /mnt
#Extract the initrd.img from the slackware dvd into /mnt cat /media/ubuntu/$InstallDVDName/isolinux/initrd.img | gzip -d | cpio -i
#Bind special linux directories into the /mnt folder for i in proc sys dev tmp; do mount -o bind /$i ./$i; done
#Mount the cdrom folder into /mnt/cdrom rm cdrom mount -o bind /media/ubuntu/$InstallDVDName/ ./cdrom
#Set /mnt as our actaul (ch)root chroot .
#Run the slackware setup usr/lib/setup/setup
#NOTE: When installing, your package source directory is at /cdrom/slackware64
15
« on: June 26, 2019, 09:53:33 pm »
It’s a bit of a pain reading results from batch requests to Mailchimp. Here is a quick and dirty bash script to get and pretty print the JSON output. It could be cleaned up a little, including combining some of the commands, but meh. #Example variables BATCHID=abc1234567; APIKEY=abcdefg-us11@us11.api.mailchimp.com; APIURL=us11.api.mailchimp.com;
#Request the batch information from Mailchimp curl --request GET --url "https://dummy:$APIKEY@$APIURL/3.0/batches/$BATCHID" 2> /dev/null | \
#Get the URL to the response grep -oP '"response_body_url":"https:.*?"' | \ grep -oP 'https:[^"]*' | \
#Get the response xargs wget -O - 2> /dev/null | \
#The response is a .tar.gz file with a single file in it. So get the contents of this file tar -xzvO 2> /dev/null | \
#Pretty print the json of the full return and the “response” objects within php -r '$Response=json_decode(file_get_contents("php://stdin"), true); foreach($Response as &$R) $R["response"]=json_decode($R["response"], true); print json_encode($Response, JSON_PRETTY_PRINT);'
|
|