Upgrade base OS:
freebsd-update fetch
freebsd-update install
Check available kernel:
freebsd-version -k
Check running kernel:
uname -r
Upgrade binaries:
pkg update
pkg upgrade
Check for binary vulnerabilities:
pkg audit -F
444 sudo pkg install e2fsprogs-core
445 gpart show
447 sudo gpart destroy -F da1
448 sudo gpart create -s GPT da1
449 sudo mke2fs -L tirana_storage -F -E discard -t ext4 /dev/da1
451 sudo mount -t ext2fs /dev/da1 /mnt
Note to self, ext4 is super slow on FreeBSD compared to UFS. I wish I could get UFS to copy on linux.
echo "~/mutt/muttrc"
# About Me
set from = "redacted-email-address"
set realname = "Yancy"
# My credentials
set smtp_url = "smtp://redacted-email-address@mail.redacted-mail-server-name.net:587/"
set smtp_pass = "redacted-password"
set imap_user = "redacted-email-address"
set imap_pass = "redacted-password"
# My mailboxes
set folder = "imaps://mail.redacted-mail-server-name.net:993"
set spoolfile = "+INBOX"
# Where to put the stuff
set header_cache = "~/.mutt/cache/headers"
set message_cachedir = "~/.mutt/cache/bodies"
set certificate_file = "~/.mutt/certificates"
# Etc
set mail_check = 30
set move = no
set imap_keepalive = 900
set sort = threads
set editor = "vim"
# Shortcut for checking on new messages
bind index G imap-fetch-mail
set sort_aux = last-date-received
echo "~/.tmux.conf"
# depends on apm for the battery status and ifconfig to fetch the current ip addr.
set -g status-right "#(ifconfig | grep wlan0 -A 2 | grep inet | awk '{print $2}') | #(apm | grep 'Remaining battery life' | awk '{print $4}') %| %a %h-%d"
run '~/.tmux/plugins/tpm/tpm'
After watching Lecture 1A of SICP, I wrote the recursive algorithm for finding the square root of a number in Rust. The algorithem implements Heron's method , named after the Greek mathematician Hero of Alexandria (what a name, right?). Although, the method was known prior to Hero. See: babylonian mathematics 1800 - 1600 BC.
const S: f32 = 2.0;
fn good_enough(guess: f32, x: f32) -> bool {
(guess * guess - x).abs() < 0.0001
}
fn improve(guess: f32, x: f32) -> f32 {
//average guess and x / guess.
(guess + x / guess) / 2.0
}
fn try(guess: f32, x: f32) -> f32 {
if good_enough(guess, x) {
guess
} else {
try(improve(guess, x), x)
}
}
fn square_root(x: f32) -> f32 {
try(1.0, x)
}
fn main() {
let square_root = square_root(S);
println!("square root: {}", square_root);
}
Recursive representation:
x(0) ~ sqrt(S)
x(n + 1) = 1 /2 ( x(n) + S/x(n) )
---
I finished ex1-16 yesterday. To this point, malloc and heap allocation hasn't been described, although I don't think it would be worthwhile to try to store the contents on the stack, so I used malloc and remalloc.
/* Excercise 1-16
*
* Revise the main routine of the longest-line program so
* it will correctly print the length of arbitrary long
* input lines, and as much as possible of the text.
*/
#include
#define MAXLINE 1000 /* maximum input line size */
int max;
char line[MAXLINE];
char longest[MAXLINE];
int get_line(char line[], int maxline);
void copy(char to[], char from[]);
/* print longest input line */
int main()
{
int len; /* current line length */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char *longest = malloc(0); /* longest */
char *complete = malloc(0); /* complete */
max = 0;
while ((len = get_line(line, MAXLINE)) > 0) {
int line_len = strlen(line);
int complete_len = strlen(complete);
complete = (char *) realloc(complete, strlen(line) + strlen(complete));
strcat(complete, line);
if (line[len - 1] == '\n') {
if (strlen(complete) > max) {
longest = (char *) realloc(longest, strlen(complete));
max = strlen(complete);
strcpy(longest, complete);
}
complete[0] = '\0';
}
}
if (max > 0) /* there was a line */
printf("%s", longest);
return 0;
}
/* get_line: read a line into s, return length */
int get_line(char s[], int lim) {
int c, i;
for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i) {
s[i] = c;
}
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
Addendum, after reading 1-16 again, I think the question assumes you don't know about malloc, and instead to just print as much of the line as possible. Here's a re-work of the problem without malloc:
/*print the longest line */
main()
{
int len; /* current line length */
int total_len; /* the total length when line spans multiple reads */
int copied_size; /* the size of the line copied */
int max; /* maximum length seen so far */
char line[MAXLINE]; /* current input line */
char longest[MAXLINE]; /* longest line saved here */
max = 0;
total_len = 0;
copied_size = 0;
while ((len = get_line(line, MAXLINE)) > 0) {
total_len += len;
if (total_len > max) {
max = total_len;
if (len > copied_size) {
copy(longest, line);
copied_size = len;
}
}
if (line[len - 1] == '\n') {
total_len = 0;
}
}
if (max > 0) /* there was a line */
printf("%d: %s", max, longest);
return 0;
}
/* copy: copy 'from' into 'to'; assume to is big enough */
void copy()
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
++i;
}
This seems to imply to[i] = from[i] has the side-effect of returning the value from[i].
#include
int main()
{
int a = 0;
int b = 1;
printf("%d", a = b );
}
The results print 1 to stdout, showing the assignment of the value b is printed.
// Add a check for visitation which fixes 20231016 version.
//
// Note to self, visited could be a node state instead.
fn dfs_iter(root: &Node, bound: usize) {
let mut visited = vec![];
let mut call_stack = vec![];
let mut path = vec![];
call_stack.push(root);
visited.push(root);
while !call_stack.is_empty() {
let node = call_stack.pop().unwrap();
path.push(node);
visited.push(node);
let sum: usize = path.iter().map(|n| n.key).sum();
if sum <= bound {
println!("* path: {:?}", path.iter().map(|n| n.key).collect::>() );
let descendants = &node.descendants;
for d in descendants {
call_stack.push(d);
}
}
if sum > bound || node.descendants.is_empty() {
path.pop();
// backtrack
loop {
let n = path.last();
match n {
None => break,
Some(n) => {
let is_explored = is_explored(n, &visited);
if is_explored {
path.pop();
} else {
break;
}
}
}
}
}
}
}
// note to self, the following iterative version does not produce the same
// results as the recursive version from 20231014. The reason being that
// once a leaf node is reached, only one node is popped instead of popping
// all the way to the root for example. One possible way to solve this is
// to add an explored state to each node and pop if the node is explored.
// A node is explored if all of it's descendants are explored.
//
// iterative dfs bound by node sum.
fn dfs_iter(root: &Node, path: &mut Vec, bound: usize) {
let mut call_stack = vec![];
call_stack.push(root);
while !call_stack.is_empty() {
let node = call_stack.pop().unwrap();
path.push(node.key);
let sum: usize = path.iter().sum();
if sum <= bound {
println!("path: {:?}", path);
let descendants = &node.descendants;
for d in descendants {
call_stack.push(d);
}
}
if sum > bound {
path.pop();
} else if node.descendants.is_empty() {
path.pop();
}
}
}
---
// recursive dfs bound by node sum.
fn dfs(node: &Node, path: &mut Vec, bound: usize) {
path.push(node.key);
let sum: usize = path.iter().sum();
if sum <= bound {
println!("path: {:?}", path);
let descendants = &node.descendants;
for d in descendants {
dfs(d, path, bound);
}
}
path.pop();
}
// dfs bound by distance.
fn dfs(node: &Node, distance: usize, bound: usize) {
println!("key: {} depth: {}", node.key, distance);
let descendants = &node.descendants;
for d in descendants {
let new_distance = distance + d.distance;
if new_distance <= bound {
dfs(d, new_distance, bound);
}
}
}
---
// dfs - non binary tree that prints the distance from the root to the leaf (depth).
fn dfs(node: &Node, distance: usize) {
println!("key: {} depth: {}", node.key, distance);
let descendants = &node.descendants;
for d in descendants {
dfs(d, distance + d.distance);
}
}
---
// dfs - non binary tree that prints the depth of each node.
fn dfs(node: &Node, depth: usize) {
println!("key: {} depth: {}", node.key, depth);
let descendants = &node.descendants;
for d in descendants {
dfs(d, depth + 1);
}
}
---
// dfs - non binary tree
fn dfs(node: &Node) {
println!("{}", node.key);
let descendants = &node.descendants;
for d in descendants {
dfs(d);
}
}
// A Node definition.
#[derive (Clone, Debug)]
struct Node<\'a> {
descendants: Vec>>,
key: usize
}
// Building a tree to search on.
// 5
// / | \
// 3 1 4
// |
// 2
let node_five = Node {
descendants: vec![
Box::new(&node_three),
Box::new(&node_one),
Box::new(&node_four)],
key: 5
};
..
// A binary search - O(height)
fn binary_search(node: &Node, target: usize) {
if node.key == target {
println!("found node that matches target: {:?}", node);
}
if target < node.key {
let left_node: &Node = node.left.as_ref().unwrap();
binary_search(left_node, target);
}
if target > node.key {
let right_node: &Node = node.right.as_ref().unwrap();
binary_search(right_node, target);
}
}
// A Node definition.
#[derive (Clone, Debug)]
struct Node<'a> {
left: Option>>,
right: Option>>,
key: usize
}
// Building a tree to search on.
let node_five = Node {
left: Some(Box::new(&node_three)),
right: Some(Box::new(&node_seven)),
key: 5
};
..
// If the input is a tree and not a graph (without cycles), then
// the solution becomes simpler since there is no need to maintain
// a visitied list.
fn dfs_tree(tree: &HashMap>, root: usize) {
println!("visit {}", root);
let branches: &Vec = tree.get(&root).unwrap();
for &node in branches {
dfs_tree(tree, node);
}
}
// The iterative version
fn dfs_tree_iter(tree: &HashMap>, root: usize) {
let mut s = Vec::new();
s.push(root);
while !s.is_empty() {
let n = s.pop().unwrap();
println!("visit {}", n);
let branches = tree.get(&n).unwrap();
for &n in branches {
s.push(n);
}
}
}
// Recursive depth first search.
fn dfs(visited: &mut HashSet, graph: &HashMap>, vertex: usize) {
// Check if the vertex has been visited.
if !visited.contains(&vertex) {
println!("visit {}", vertex);
// It hasn't been visited, so mark it as visited now.
visited.insert(vertex);
// Get all edges of this vertex.
let edges: &Vec = graph.get(&vertex).unwrap();
// For each child, visit.
for &v in edges {
// Recusive call.
dfs(visited, graph, v);
}
}
}
// Iterative depth first search.
fn dfs_iter(visited: &mut HashSet, graph: &HashMap>, vertex: usize) {
let l = graph.len();
// The stack will never be larger than the graph.
let mut s: Vec = Vec::with_capacity(l);
s.push(vertex);
while !s.is_empty() {
let v: usize = s.pop().unwrap();
// Check if the vertex has been visited.
if !visited.contains(&v) {
println!("visit {}", v);
// It hasn't been visited, so mark it as visited now.
visited.insert(v);
// Get all edges of this vertex.
let edges: &Vec = graph.get(&v).unwrap();
for &v in edges {
s.push(v);
}
}
}
}
// Entry point.
fn main() {
// A hashmap of tuples which represent a graph. The first item is the vertex,
// and the second item which are edges.
let mut graph = HashMap::from([
(5 , vec![3, 7]),
(3 , vec![2, 4]),
(7 , vec![8]),
(2 , vec![]),
(4 , vec![8]),
(8 , vec![])
]);
let l = graph.len();
// Start DFS at the root node 5.
// Set of visited (no duplicates)
let mut visited: HashSet = HashSet::with_capacity(l);
dfs(&mut visited, &mut graph, 5);
..
}
-
echo "Editing files on a remote machine with vim"
vim scp://username@hostname/
-
cat .bash_profile
eval $(keychain --eval --agents ssh id_ed25519)
-
echo "setup keychain"
cd /usr/ports/security/keychain/ && sudo make install clean
echo "eval $(keychain --eval --agents ssh id_rsa)" > ~/.bash_profile
[1]
cat .vimrc
execute pathogen#infect()
syntax enable
filetype plugin indent on
" ctrlp
set runtimepath^=~/.vim/bundle/ctrlp.vim
" fix backspace
set backspace=indent,eol,start
" Shortcut to rapidly toggle `set list`
nmap l :set list!
" tabstop: Width of tab character
" softtabstop: Fine tunes the amount of white space to be added
" shiftwidth Determines the amount of whitespace to add in normal mode
" expandtab: When this option is enabled, vi will use spaces instead of tabs
set tabstop =2
set softtabstop =2
set shiftwidth =2
set expandtab
-
cat .xinitrc
# Set background image
feh --bg-max ./Downloads/awesome-destop.jpg
# Start evilwm
/usr/local/bin/evilwm -snap 10
-
echo "setting up the homepage droplet"
# Add a new user
sudo useradd -m {username} -s /bin/bash
sudo passwd {username}
# Add a sudoer
vim /etc/sudoers
user_name ALL=(ALL) ALL
# Setup Git
sudo apt-get install git
cd ~ && git clone git@github.com:yancyribbens/homepage.git
# Setup nginx
sudo rm /var/www/html/index.nginx-debian.html
sudo ln -s ~/git/homepage/index.html /var/www/html/index.nginx-debian.html
# Enable ssh for new user (copy the keys file from root)
cp /root/.ssh/authorized_keys /home/yancy/.ssh/authorized_keys
chown user:user /home/user/ssh/authorized_keys