code:
#+AUTHOR:Joshua Branson
#+TITLE: C cheatsheat
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}
#+OPTIONS: H:10 toc:nil
* C cheatsheat
** How to say complicated C declarations

http://www.programmerinterview.com/index.php/c-cplusplus/c-declarations/

Begin looking at the variable name.
1) without skipping a right parenthesis, look right and say what you see.
2) Without skipping a left parenthesis, look left and say what you see.
3) If you are inside a parenthesis, move out of it move to the right to see what you see.
4) Look left and see what you see.  Start again from 1 if need be.

~int (*a)[3];~

Begin by looking at a.
1) Go right and a and hit a right parenthesis.  Do not say anything.
2) Go left of a and say what you see.  Do not pass a left parenthesis.  A pointer.
3) Go outside the parenthesis and see an array of size 3.
4) Go left and see an int.

   SO,  a is a pointer to an array of 3 ints.

~char *i[2][8];~
1) Move right of i and say array of size 2 and an array of size 8.
2) move let of i and say pointer
3) a char

   i is an array composed of 2 arrays of 8 pointers to chars.

~char *(*a[ 3 ])();~

a is an array of size 3 pointers to functions, returning an char pointer

~int (*t[])();~

t

t is an array of points to function returning an int.
** tersely written while loops
#+BEGIN_SRC C
  while (c == getchar())
    putchar (c);
#+END_SRC
** variables and scope
*** automatic variables  aka the default variable scope
Most variables are local to the function that calls them.  That is, any variables declared in a function die when the function exits. For example, the following function =add=, creates the variables a and b in the main function.  BUT they disappear after the function ends.
#+BEGIN_SRC C
  int
  add (int a, int b) {
    return a + b;
  }

  int
  main () {
    printf ("the sum is %s", add (3, 4));
    printf ("a is %s, b is %s", a, b); /* results in error,
                                          because main can't
                                          access a or b. */
    return 0;
  }
#+END_SRC

*** Static varibles
There are also static variables that are static, which keep their values each time they are called.  If you are trying to write functional code, then only use these variables.

#+BEGIN_SRC C :results replace
#include <stdio.h>
  int count () {
    static int b = 0;
    return b++;
  }

  int
  main () {
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    printf ("b is %s\n", count());
    return 0;
  }
#+END_SRC

#+RESULTS:

The output of the above would be

#+BEGIN_SRC C
"b is 1"
"b is 2"
"b is 3"
"b is 4"
#+END_SRC
*** external variables (global)
External variables are variables that are accessible to any function.  They can be thought of as global variables, because any function has access to these global variables.  Never use this functionality.  This is NOT functional programming.  Using global variables usually means that your program will have to run synchrously and not use any threads.  It can also lead to some odd errors.

#+BEGIN_SRC C
#include <stdio.h>

//this is an external variable.  It exists outside all the other functions that call it.
int count = 5;

int add (int a) {
  extern int count;
  return count + a;
}

int
main () {
  extern int count;
  printf ("count == %d\n", count);
  printf ("add (1) == %d \n", add(1));
}
#+END_SRC
** types
*** char
  a singly byte capable of holding 1 character.  A character is any character in ASCII.  It's the english alphabet plus some other characters like "@", "!", "#", "$", "%", etc.

  #+BEGIN_SRC C
  /* Is the ASCII number representing x. */
  char number = 'x';
  /* is the char array "x\0" */
  char x []  = "x";
  #+END_SRC

*** int
  A whole number that can be negative or positive.
  One can also use octal or hexidecimal to define a number
  #+BEGIN_SRC C
    int x = 31;
    /* the same value in octal */
    int x = 037;
    /* int the same value in hexidecimal. */
    int x = 0x1f;
    int x = 0X1F;
  #+END_SRC

  - short int
  - long int
  - unsigned int
    This number is only positive.
  - signed int
    This number is positive and negative.  Dy default "int" is equivalent to "signed int".
*** float
*** double
*** const
  This means that the value will not change.
  #+BEGIN_SRC C
    /* this value cannot be changed. */
    const int x = 6;
  #+END_SRC

I believe that this is a constant too.
#+BEGIN_SRC C
#define NEWLINE '\n'
#+END_SRC
*** enum
The Enumeration constant is a list of constant integer values.  It can often be used for boolean values:

#+BEGIN_SRC C
enum boolean { NO, YES };
#+END_SRC

By default the first element in the list has a value of 0, the next 1, and so on.

You can enumerate the months like so,

#+BEGIN_SRC C
enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };
#+END_SRC

** printing arrays
#+BEGIN_SRC C
printf ("%s", "Hello World\n");
#+END_SRC

#+RESULTS:
: Hello World
** Declarations
A variable must be defined, before it can be used.  The following two snippets are identical:

#+BEGIN_SRC C
char my, how, why;
float a, x[1000];
#+END_SRC

#+BEGIN_SRC C
char my;
char how;
char why;
float a;
float x[1000];
#+END_SRC

You can also declare variables with a value:

#+BEGIN_SRC C
char a, b, c = 5;
int o, y, z = 8;
#+END_SRC
** control flow
*** if, else if, else
*** switch

switch (expression) {
   case const-expr: statements
   case const-expr: statements
   default: statements
}

The switch statement is a cool way have multiple if else statements in a better fashion.

I normally use it like so:

#+BEGIN_SRC C :tangle no
  switch (opt)
    {
      // if this parser function is called on an option that it doesn't recognize, then don't do anything.
    default:
      return ARGP_ERR_UNKNOWN;
    case 'j':
      {
        printf ("What do you call a box full of ducks?\n");
        printf ("A bunch of quackers.\n");
        break;
      }

    case 'm':
      {
        //some code
        break;
      }
    }
#+END_SRC

BUT there are cooler ways to use the switch statement!

#+BEGIN_SRC C
  switch (digit) {
   case: 'A' case: 'B' case 'C':
     {
       //some code
     }

   case: 5 case: 7 case: 9
       {
         //some code
         break;
       }
   default:
     //some code
     break;
   }
#+END_SRC
*** for loops

initialize i to be equal to 0, while i is less than 5, do some code.
#+BEGIN_SRC C
for (int i = 0; i < 5; i++) {
//code
}
#+END_SRC

** cool libraries
*** ctype

#+BEGIN_SRC C
isdigit ('c'); //returns false aka non-0.
#+END_SRC

#+BEGIN_SRC C
tolower ('Y'); // returns y
#+END_SRC

#+BEGIN_SRC C
toupper ('z');; // returns z
#+END_SRC
** functions
*** functions may be defined within other functions
** macros

#+BEGIN_SRC C
#define max(A,B)  ((A) > (B) ? (A) : (B))
#+END_SRC

You can also undefine macros.  You might do this to make sure that you are using a function and not a macro:

#+BEGIN_SRC C
#undef max

max (a, b);
#+END_SRC

* virtual memory and paging

A common method of managing memory is by using virtual memory.  Virtual memory is memory that is mapped to physical memory, but usually there is more virtual memory than there is physical memory.  A computer may have 5 GB of real memory, but 6 GB of virtual memory.

Virtual memory is split up into pages, which are normally 4KB each.  A virtual memory page references a real memory page, which is called a frame.  So frames are real memory and pages are virtual memory.

It's like a mormon marriage.  You're supposed to have 1 wife, but the husband gets multiple women.

A process has a page associated with it, but sometimes memory is short and the process' page is not connected to a frame.  When the process tries to use the virtual page, and the virtual page tries to access the frame, this is called a page fault.  When this happens the kernel suspends the process and connects the page to a frame.  Then the kernel starts the process again, and the process thinks that the page was connected to a frame.

It's actually possible to lock pages.  Suppose you have a realtime application that cannot accept page faults, then you can lock that page.  You could also do the same for security sensitive information.  If a process has stored your password, you want that memory only in real memory.  You never want it to get sent to swap...  But locking pages can cause a performance penalty.  If all programs lock pages, then no programs can run.
* argp (argument parsing)

Many C command line programs accept arguments.  Just type =git --help= in a command line to see what I mean.  argp is GNU's standard for dealing with arguments passed to C programs.  Most people will probably only need to call argp_parse in the main function to start using it.

It's a good idea to set some default variables:

=const char * argp_program_version = "VERSION_NUMBER";=
=const char * argp_program_bug_address = "EMAIL_ADDRESS";=
** creating argument parsers

An argument parser is a struct. You probably will need to define options, parser, args_doc, and doc.

#+BEGIN_SRC C
struct argp argp;
#+END_SRC

*** options

The options is just a list of options that this program understands.  Options can be -CHAR or -NAME.

-CHAR is of the form "-g" or "-h" or "-i".

-NAME is of the form "--get" or "--help" or "--i"

For example, one can create an arg_options struct like so:

#+BEGIN_SRC C
  struct argp_option argp_options_joke;
#+END_SRC

Let's suppose you want to make an option that prints a silly joke.  To make the long option be "--joke" you need:

#+BEGIN_SRC C
  argp_options_joke.name = "joke";
#+END_SRC

To have the short option be "-j" :
#+BEGIN_SRC C
  argp_options_joke.key  = 'j';
#+END_SRC

This field needs a name so that argp can associate the option with a parser.
#+BEGIN_SRC C
  argp_options_joke.arg  = "joke";
#+END_SRC

And a doc string
#+BEGIN_SRC C
  argp_options_joke.doc  = "Print a funny joke.";
#+END_SRC

You can also make the option NOT need an argument.  For example the "--help" does not have an argument, but the "rm -r" does require an argument.  In this case "rm -r" requires the file/directory to delete.

#+BEGIN_SRC C
  argp_options_joke.flags = OPTION_ARG_OPTIONAL;  // this option does not need an argument.
#+END_SRC

Now you need to turn this option into an array that can be passed to your argp.options variable.

Notice that the "{ 0 }".  struct argp_option options [2] needs to be a list with the last element in the list having 0 in all of its fields.  "{ 0 }" is the C shortcut for that.

#+BEGIN_SRC C
struct argp_option options [2] = { argp_options_joke, { 0 } };
argp.options = options.
#+END_SRC

*** args_doc
This is the usage string that you print when someone calls your program with PROGRAMNAME --help.

#+BEGIN_SRC C
argp.args_doc = "argp [options]";
#+END_SRC
*** doc

This is the documentation paragraph that explains what your program does.

#+BEGIN_SRC C
argp.doc = "Just a simple test argp program!";
#+END_SRC
*** argp parser functions

argp_parse parses the arguments via an argument parser.  The argument parser could be a null pointer.

The easiest way to use argp to parse options is to use one function to parse all options.  This function needs to look like this:

     =error_t PARSER (int KEY, char *ARG, struct argp_state *STATE)=

The options field in a struct argp points to a function.  Every time this parsing function is called, it parses a command line option.  If the user typed in -j, then KEY equals 'j'.  If the user typed in -g, then the key field equals 'k'.  So you could implement a basic parser function to parse each argument based on what KEY equals.  ie:

#+BEGIN_SRC C :tangle no
error_t
     parse_opt (int key, char *arg, struct argp_state *state)
     {
       switch (key)
         {
         case 'j':
           //some ACTION code here
           break;
         case 'g':
           //some different ACTION code here.
Daisy theme documentation: [[gnus:nnimap+imap.fastmail.com:INBOX#CAHD1g8WjE_jHcX211TYbjZvZWoZdcQF_+2u5s6yq+eaKoDE4XQ@mail.gmail.com][Email from Lindsay V.: Re: Doing some updates]]
           break;
         default:
           return ARGP_ERR_UNKNOWN;
         }
       return 0;
     }

#+END_SRC
* writing a test to prove I know C

[2018-10-30 Tue] I took this test and got a 71%

** what is the [[info:libc#Aborting%20a%20Program][abort]] function?

:answer:
It is a way to abnormally terminate a program.

It does not allow cleanup functions registered with atexit or on_exit.

This function actually terminates with the SIGABRT signal.  My program can include a handler to intercept this signal.
:END:

** types
   What's the differance between a double, float, short, int, long, char,
   etc.

   Write some examples of floating numbers, etc.

   ie:  9f

   Write some hex numbers...
*** How do you write a long double constant?  What letter to you put at the end of the number?

    :ANSWER:
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      int a = 500L;

      int b = 500l;
    #+END_SRC
    :END:
*** How do you write a unsigned long constant?  How do you postfix the number?
    :ANSWER:
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      int a = 240UL;

      int b = 212ul;
    #+END_SRC
    :END:
*** What is wrong with this statement
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      short int a = 240UL;
    #+END_SRC

    :ANSWER:
    The declaration (aka "short int a"), implies that a is a short
    integer.  But the definition (240UL), implies that A is an
    unsigned long.  The compiler will probably complain that our
    declaration and definition do not match.
    :END:
*** What is wrong with this statement
    #+HEADERS  :includes <stdio.h>
    #+BEGIN_SRC C
      short int a = 240f;
    #+END_SRC

    :ANSWER:
    The declaration (aka "short int a"), implies that a is a short
    integer.  But the definition (240f), implies that A is a floating
    integer.  The compiler will probably complain that our declaration
    and definition do not match.
    :END:
*** Why does C include Hex and octal numbers?  Why don't they just use decimal numbers?

    Because computers only understand 1s and 0s.  There is a conversion
    penalty every time the computer has to convert back and forth between
    binary numbers and decimal digits.

    Using Hex numbers can be useful when printing pointer addresses.  A
    program pointer points to a region of memory.  Suppose that a pointer
    address is at the 10,995 byte.  One can write this is binary like
    =0b0010101011110011= or in hex =0x2AF3=

    every 4 bits (a nibble), can be represented by one digit in Hex.  This
    saves space.

    I still don't know why pointer address's aren't just printed in
    decimal form though.

** do some function pointers
** if I add in "type.h", then it refuses to [[file:~/programming/c/minify/minify-html.c::/*%20#include%20"types.h"%20*/][compile]]
   :PROPERTIES:
   :ID:       9ac4e026-d625-43cc-acec-ba39de698537
   :END:

   why don't [[file:~/programming/c/minify/minify-html.c::/*%20#include%20"types.h"%20*/][this compile?]]
** make some new types aka typedefs

   :ANSWER:
   C does not allow one to extend the language by creating unique new
   definitions.  Rather, it allows one to extend existing types: int,
   long, double, etc.

   This is useful for aesthetic and portability reasons.  Consider the
   following:

   #+BEGIN_SRC C
     typedef struct complicatedStruct {
       char ** bread;
       int toppings [5];
       double *weight;
       float *size;
     } burger;

     // now we can create as many burgers as we want

     burger quarterPounder, halfPound, heavyBurger;

   #+END_SRC

   This can be helpful for portability reasons as well.  Consider a machine that does not have the "float" value.  Then to port the program, all we need to change would be the various typedefs.  Typedefs can also be useful with complicated structures and function pointers like my [[file:~/programming/c/function-pointer.c::int%20(*pAdd4)%20(%20int%20(*%20pAdd3)%20(int%20(*%20pAdd)%20(int,%20int),%20int,%20int,%20int),][function pointer.c]] files shows.

   :END:
*** create a function pointer tydedef
:ANSWER:
#+BEGIN_SRC C
typedef int (*functionPointer) (int *, int);
#+END_SRC

:END:

*** create a structure typedef

#+BEGIN_SRC C
  typedef struct {
  char *word;
  char **string;
  char array [];
  } tnode;
#+END_SRC
** vocab
*** what's the stack?
**** print the top two elements of the stack

The stack is what you get your automatic variables.  AKA variable that you don't have to allocate space for via malloc.
*** what's the heap?

The heap contains all of the variables you have got via malloc calls.
*** what's the difference between the stack and the heap

The stack is automatic variables, but the heap is global variables...

The heap are variables that you get via calls to malloc.

The stack are variables you don't have have to use malloc, aka normal or automatic variables.
*** difference between a union and a struct

    :ANSWER:
    Both a union and a struct are an easy way of collecting variables
    under one variable name.  The difference is a struct's collection
    can define all values simultaneously.  A union's collection is
    only allowed to define one variable at a time.
    :END:
*** what's a declaration and a definition and an assignment?

   :ANSWER:
   A declaration is a promise to the compiler that a function or variable exists.

   A definition is the section of code that allocates a region of memory for the variable or function.

   #+BEGIN_SRC C
     #include <stdio.h>
     int a;     // declaration
     int add (int a, int b);

     int main () {
       a = 5; //this is the assignment statement
       int b = 10; //I am also an assignment statement

       int c = add (a, b);
       printf("%d\n", c);
       return 0;
     }

     //definition
     int add (int a, int b) {
       return a + b;
     }
   #+END_SRC

   #+RESULTS:
   : 15

   :END:
*** what's a segmentation fault
    :ANSWER:
    Your program tried to access memory to which it did /not/ have access.
    :END:

*** what are the 4 common types of segmentation faults otherwise known as segfaults?

    # retrieved from https://www.cprogramming.com/debugging/segfaults.html

    :ANSWER:
    There are four common mistakes that lead to segmentation faults:
    - dereferencing NULL
    - dereferencing an uninitialized pointer
    - dereferencing a pointer that has been freed (or deleted, in C++)
      or that has gone out of scope (in the case of arrays declared in
      functions)
    - writing off the end of an array.
    :END:

*** what's a stack overflow?
    :ANSWER:
    Your recursive function used up all of the stack space.  You have
    no more memory to continue recursing.
    :END:

*** parameter

    :ANSWER:
    The parameters are the local variables that are shown in the
    function definition.
    :END:

*** argument

    :ANSWER:
    An argument is the value that is passed to the function.
    :END:

*** what is a statement?
    Functions are made up of statements, which specify computing
    operations to be done.  Statements are usually one line long and
    end in ";".

** demonstrate proficiency in multidemensional arrays
** argp
** what is the /etc/nsswitch.conf file?

   :answer:
   It is a place to store various information about the system so that
   applications work smoothly together.

   /etc/hostname stores the computer's hostname.  That's how the C
   library and everything else know the computer's hostname.

   /etc/nsswitch.conf configures other things.
   :END:

** what are some things you could put in the /etc/nsswitch.conf file?

   :answer:
   - email aliases
   - passwords
   - public keys
   - groups of users
   - etc.
   :END:

** threading
** what's the differance between malloc and alloc?

   :answer:
   malloc lets you explicitly allocate memory, and you are responsible
   for destroying that memory.

   With alloc you can get memory for yourself, and when you leave the
   function that alloc is called from, the memory is freed
   automatically!  So it's really easy to use, and maybe better!
   :END:

** multi-processing
** do some of the coding challenges provides in my C book
** what's the differance between a pipe and a FIFO?

A pipe has no name.  Only the parent and it's children can communicate with the pipe.

A FIFO is a communication that names a name.  Anyone can open it and communicate to it.
** learn valgrind
http://valgrind.org/docs/manual/quick-start.html#quick-start.mcrun

If run your program with arguments like:  main arg1 arg2,

Then you can run valgrind to test for memory errors like this:

  valgrind --leak-check=yes myprog arg1 arg2

memcheck is the default tool.  --leak-check=yes turns on the detailed memory checker.
** learn complicated declarations

They are read right to left.

** learn programs that tell you how fast your C code is.
** what are signals?
:answer:
Signals are ways for your programs to declare certain events to have happened.
:END:
** What does it mean when a program is given an error signal from the OS?
:answer:
This generally means that the program must stop executing.  Some massive problem has broken significant program logic, exposed a security vulnerability, etc.  Programs can at this time write a core dump file and then return control to the OS to end the program.  This dump file is useful for investigating what caused the crash.
:END:

** how does a C compiler work? initialization
** recursion
** type conversion

Suppose you wish to add an int and a float.  C does a conversion for you.  Generally, the automatic conversions convert a small type to a larger type, so you won't lose information.  IE: C will convert an int into a float to add an int and a float.

#+BEGIN_SRC C :includes <stdio.h>
    int i = 2;
    float f = 3.0;

    printf("%f\n", i + f);
#+END_SRC

#+RESULTS:
: 5.0

** how to code functionally in C?
** #include <filename> vs. #include "filename"?

:ANSWER:
=#include <filename>= is for standard libraries.

=#include "filename"= is for libraries that I write.
:END:

** make a multi-filed C program
** make a portable C program
** learn autotools
** learn macros
*** learn glibc macros
** conditional inclusion:
   #+BEGIN_SRC C
   #if !defined (HDR)
     #if SYSTEM == BSD
      #define HDR "bsd.h"
     #elif SYSTEM == LINUX
      #define HDR == "linux.h"
     #else
      #define HDR "msdos.h"
     #endif

     #include HDR
   #+END_SRC
** learn printf

   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     float f = 39403.29304;
     printf ("%%f %f\n", f);
     printf ("%%2f %2f\n", f);
     printf ("%%2.0f %2.0f\n", f);
     printf ("%%100.100f %100.100f\n", f);
   #+END_SRC

   #+RESULTS:
   | %f        |   39403.292969 |
   | %2f       |   39403.292969 |
   | %2.0f     |          39403 |
   | %100.100f | 39403.29296875 |

   :ANSWER:
   %d is for decimal
   %6d  is a decimal integer at least 6 characters wide
   %f floating point
   %6f is a floating point at least 6 characters wide
   %.2f  print as a floating point and add two characters after the decimal point
   %6.2f  print as a floating point.  Print 6 characters before the decimal and 2 after
   %o is for octal
   %x for hexadecimal
   %c for character
   %% is for the "%" character.
   :END:

** file descriptors
** Convert these mathematical statements to C statements

   - (3 / (2 * 4 ^ 9)) - 23 * (4 - 3)
   - π / 23 * (4 / 23)
   - ℇ * 33 (that is Euler's constant)
** specific questions
*** How many bytes does the following string array need?

"Hello\n"

:ANSWER:

7 bytes
|---+---+---+---+---+----+----|
| H | e | l | l | o | \n | \0 |
|---+---+---+---+---+----+----|
:END:
*** What is a global variable in C called? And how would you declare "int n;" to be global?

:ANSWER:
external

#+BEGIN_SRC C
extern int n;
#+END_SRC

:END:
*** How would you define an extern variable inside the function main?

:ANSWER:
You can't.

External variables must be declared outside any function, and they must be declared inside any function that wants to use them.

You can do this though:

#+BEGIN_SRC C
  #include <stdio.h>
  int n;

  int main () {
    extern int n;
    n = 10;

    return n;
  }

#+END_SRC

:END:
*** what's the difference between these definitions/definitions 'char string [] = "hello";' 'char * string = "hello";'

:ANSWER:
This is a string array.
#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C
char string [] = "hello";
printf("%s\n", string);
#+END_SRC

#+RESULTS:
: hello

It is stored in continuous, read/write region of memory like this:

|---+---+---+---+---+----|
| h | e | l | l | o | \0 |
|---+---+---+---+---+----|

I am allowed to alter any character in the string. So
#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C
char string[] = "hello";
string[2] = 'w';
printf ("%s\n", string);
#+END_SRC

#+RESULTS:
: hewlo

This is a string literal
#+BEGIN_SRC C
char * string = "hello";
#+END_SRC

It is stored in a continuous, readonly section of memory like this:

|---------|
| hello\0 |
|---------|

So trying to modify the string results in an error
#+HEADERS: :includes <stdio.h> :var string="hello"
#+BEGIN_SRC C
//char * string = "hello";
string[2] = 'w';
printf ("%s\n", string);
#+END_SRC

#+RESULTS:

:END:
*** What is the function to break a string into tokens?

:answer:
strtok
:END:

*** Describe C's presidence rules...

:ANSWER:
Highest presidence to lowest.   The arithmatic rules are PEMDAS.  So C does not need parenthesis when evaluating
basic arithmetic.

,* /
+ -
> >= < <=
,==   !=
&&  ||
:END:
*** what's the difference between a void function and a static void function?

A void function, can be called by any bit of code in your project.  A static void function, can only be used in the source code file it is in.  This is useful for large projects.  Many drivers in the linux kernel are named static void, so that they do not conflict with any other functions in the linux kernel.
*** what's MT-safe, AS-safe, and AC-safe mean?

:answer:
In POSIX safety terms these refer to if it is safe to call various functions.

MT-safe means that it is safe to call this function inside a thread.  This does not mean that the function is atomic.
:END:
*** What is the difference between 'a' and "a"?

    :answer:
    'a' is a character.  "a" is a string.  "a" is internally
    represented as {'a','\0'}.
    :END:

** which hurd library is great to develop virtual directory structures like /proc?

:answer:
libnetfs

This is the library that NFS is built on.
:END:
** what is the following output of this C program

#+BEGIN_SRC C
#include <stdio.h>

int main () {
   int *p = 15;
   printf("%d",*p);
   return 0;
}
#+END_SRC

#+RESULTS:

:answer:
A runtime error.  The pointer is not pointing to a proper location in memory.
Trying to read from an undefined point in memory, will cause a segmentation fault.
:END:
** What is the output of these lines of code?

   #+HEADERS: :includes <stdio.h>
   #+BEGIN_SRC C
     printf ("%d\n", 5/9);
     printf ("%d\n", 5.0/9.0);
     printf ("%f\n", 5.0/9.0);
   #+END_SRC

   :answer:
   #+RESULTS:
   |        0 |
   |  4202507 |
   | 0.555556 |
   :END:

   Why do they have different output?

   :answer:
   The integers 5 and 9 are integers.  However 5.0 and 9.0 are
   considered floating point numbers.  Floating point numbers may have
   information after the decimal point.
   :END:

* I/O

Input is reading data.  Output is writing data.  Glibc provides several functions for doing both!

I can read/write to a file by using a stream or a file descriptor.  The stream is supposed to be easier to use.  The file descriptor method is very low level, and streams are built a-top it.  Streams allow 3 different types of buffering.

Streams allow for getting in character by character, or by line by line.

Apparently I should focus on formatted input and formatted output programs...

I will also have file positions.  Whenever I am reading a file, some integer keeps track of where I am in the file.  If I read a byte forward, then that integer increases by 1.

Streams use file pointers.  This is stuff in stdio.h.  I can check to see if I have found the end of the file by calling:

int feof (FILE * STREAM)  it returns non-0 if the end of file is found.

When I call my main function, three streams are defined: stdin, stdout, and stderr.  cool eh?

I can even re-direct stderr to a file:

#+BEGIN_SRC C
  fclose (stdout);
  stdout = fopen ("standard-output-file", "w");
#+END_SRC
** streams
*** Open a stream
file * fopen (const char * FILE, const char * OPENTYPE)

Opentype can be: "r", "w", "a", "r+", "w+", "a+", "m".

"r" is just for reading a file.

"w" is just for writing a file and the previous file contents are discarded.

"a" is for appending at the end of the file.

"r+" is for reading and writing to a file.  This is probably the most useful.

"m" is for opening files via mmap.  It is only used for reading.  This is the function that the Hurd [[file:/ssh:joshua@localhost#2222:/home/joshua/programming/hurd/trans/hello.c::*data%20=%20mmap%20(0,%20amount,%20PROT_READ|PROT_WRITE,%20MAP_ANON,%200,%200);][hello]] program uses.
*** fclose closes the file stream.
int fclose (FILE * stream)
*** putc and fputc

These are how to write one character.  Pretty easy.

put c (int C, FILE * STREAM)
*** puts and fputs

This writes a string to a FILE *.

puts (const char *S, FILE * STREAM)
*** fgetc or getc

These functions get one character from a stream.  It's normally best to use getc, because it's faster.
*** moving the position of the file pointer

fseek (FILE * STREAM, long int OFFSET, int WHENCE)

WHENCE can be SEEK_SET, SEEK_CUR, SEEK_END to indicate if the offset is the relative to current file pointer position, the end of the file, or the beginning of the file.
** perror
is a function that lets you write an error message to the stderr stream.
* pattern matching via regexp
[[info:libc#Regular%20Expressions][info:libc#Regular Expressions]]

This is all stored in regex.h

One first needs to compile a regexp via regcomp (), then one needs to search for matches via regexec ().  Regexec will store the matches in an array that you pass into it.

compiled regular expressions are stored in the data structure regex_t.  Every regex_t has one field that I need: a re_nsub, which holds the compiled regular expressions.

The array has elements of type regmatch_t.  It has two fields:

- rm_so the offset from the beginning of the string.  Add the pointer to the string + rm_so to get the match.

- rm_eo the offset from the end of the string.

  After you have found your matches, be sure to free up the space your compiled regex was using via regfree

#+BEGIN_SRC C :tangle no
regfree (regex);
#+END_SRC
** troubleshooting

grep shows the proper matches in the white-space.txt file:

#+BEGIN_SRC sh :results output :exports both :dir ~/programming/c/
grep -E '[^ ] +$' white-space.txt
#+END_SRC

#+RESULTS:
: This line has extra white space
: this one does bro
: This line definitely has some white space.

BUT this regex doesn't match when I use the C version.  But it does match when I remove the "$".
* searching and strings

    #+HEADERS: :includes <stdio.h> <string.h>
    #+BEGIN_SRC C
      char hello [32] = "Hello World!";
      char * string;
      string = memchr (hello, '!', strlen(hello));
      printf ("%s\n", string);
    #+END_SRC

    #+RESULTS:
    : !
** How do you search trees?

:answer:
tsearch
:END:

* watch some C videos
https://www.youtube.com/user/jstrosch/videos?sort=dd&view=0&shelf_id=1
* data types
** char
** int
** float    single precision floating point
** double   double precision floating point
* qualifiers
These data types do have some qualifiers that can be applied to them.

#+BEGIN_SRC C :tangle no
short int n;
long int m;
#+END_SRC

The above is the same as:

#+BEGIN_SRC C
short n;
long m;
#+END_SRC

You can think of this like sql data types.  a short may have a value between -128-127.  "int" is no smaller than a short, and no larger than a long.
The compiler is free to determine these sizes, based on the hardware.

unsigned or signed may be used for chars and any integer. An unsigned variable's value can never be negative. A signed variable's value can be negative or positive.

#+BEGIN_SRC C
signed int n;
unsigned char c;
signed float f;
long unsigned double d;
#+END_SRC

The qualifier long applied to a double means to make the variable extra precise.

I can specify that a value in C will not change.  If this value is changed, the program will probably abort.
#+BEGIN_SRC C
const int n = 5;
#+END_SRC

* Writing in hexadecimal or octal or scientific notation
** Writing a number is scientific notation

#+BEGIN_SRC C
int n = 101e2;
printf ("%d\n", n);
#+END_SRC

#+RESULTS:
: 10100

#+BEGIN_SRC C
float f = 1.01e2;
printf ("%f\n", f);
#+END_SRC

#+RESULTS:
: 101.0
** writing in binary  this is a GNU extension

#+BEGIN_SRC C
int n = 0b11;
printf ("%d\n", n);
#+END_SRC

#+RESULTS:
: 3

* structs

A struct is a collection of data grouped under one variable name.  This is convenient for large programs with lots of data.  Consider a registration program that is responsible for registering many users.  Each user has a name, address, phone number, etc.  A convenient method for handling this kind of problem is to use a struct.

#+BEGIN_SRC C
  struct human {
    char * phone_number;
    char * name;
    char * address;
  };
#+END_SRC

Then to declare variables of this type one would do the following:

#+BEGIN_SRC C
struct human phil, john, james;
#+END_SRC

Now we have three variables "phil", "john", and "james".  We could now start filling in their information:

#+BEGIN_SRC C
phil.name = "Phil";
john.name = "John";
james.name = "James";
#+END_SRC

We could also do all of the above like this:

#+BEGIN_SRC C
  struct {
    char * name;
    char * phone_number;
    char * address;
  } james, john, phil;

  phil.name = "Phil";
  john.name = "John";
  james.name = "James";
#+END_SRC

But it's more convenient to give the struct a /tag/.  The tag in this case is "human".

Probably the easier way to do all of the above is to do the following:

#+BEGIN_SRC C
  struct human {
    char * name;
    char * phone_number;
    char * address;
  };

  struct human james =  { "James" , "7652834019", "1128 Liby Way New York"   };
  struct human john  =  { "James" , "7642824513", "1128 Liby Way New Jersey" };
  struct human phil  =  { "Phil"  , "7652434074", "1128 Liby Way New York"   };
#+END_SRC

An even easier way would probably be to use a typedef.

#+BEGIN_SRC C
  typedef struct shuman {
    char * name;
    char * phone_number;
    char * address;
  } human_t;  //the "_t" is a hint that this is a typedef

  human james =  { "James" , "7652834019", "1128 Liby Way New York"   };
  human john  =  { "James" , "7642824513", "1128 Liby Way New Jersey" };
  human phil  =  { "Phil"  , "7652434074", "1128 Liby Way New York"   };
#+END_SRC

Here's we've created a structure, and we have given it the typedef "human".  Now we can use this as a way to create new struct "shuman".

** nested structures

We can also nest structures.  Suppose we wanted to create a structure that is a family!  We can do that pretty easily too!
* C coding projects
** writing a basic html parser with the goal of minimizing html files

The way I had thought about doing it at first was to use the libc function strtok, which takes a string, and returns many substrings based on a set of string of characters.

In other words, strtok removes special characters and only returns the strings between those special characters.

So if the string is "<Hello> and </Hello>", and the delimiters are "<" and ">", then multiple calls to strtok returns

strtok () -->  Hello
strtok () -->   and
strtok () -->  Hello

This method worked when I was testing my logic.  Instead of specifying an html file, I hardcoded an html string in the file:

#+BEGIN_SRC C
const char * string = "<html>real simple</html>";
#+END_SRC

BUT now that I want to parse an html file, I may have found a better function:  getdelim.  getdelim let you read a token from a file.  So I probably won't have to use strtok anymore!  I can just read the file via getdelim and specify that "<>" are my delimiters.  The only problem is the getdelim is get delimiter not get "delimeters".  So getdelimiter only supports setting a char delimeter.  Not a string of delimeters.

I have three possible solutions:

I could ask online...
- I could write a getdelimeters function...
  - search based   (lots of back and forth of the file)...
  - two different streams for the same file  ()
  - pass over the file with getdelim once with "<", then pass over the file with ">"
  - I could use two loops.  The first loop, uses getdelim "<" and the inner loop uses getdelim ">".
  - parse the whole file into a string, and then use strtok. https://stackoverflow.com/questions/174531/easiest-way-to-get-files-contents-in-c
  - memory map the file into memory via mmap

The main problem with this technique is that the function has a hard time processing elements with contents.

ie:  <p>Hello World</p>

In the nested while loop, getdelim("<") will return the opening p element, but may forget about the p's content.  I could use static variables to get around this.

    #+HEADERS: :includes <stdio.h>
    #+BEGIN_SRC C :dir ~/programming/c/
      FILE * file = fopen ("simple.html", "r");
      char ** token;

      const char * getdelimeters (FILE * file, char ** token)
      {
        while ((token = getdelim (token, 128, "<", file)) != NULL)
          {
            //if token does not contain ">"
            return token;
            while ((token = getdelim (token, 128, ">", file)) != NULL)
              {
                //I'll use a static variable here to store the content...
                return token;
              }
          }
        return NULL;
      }

      while ((token = getdelimeters (file, token)) != NULL)
        {
          printf ("Hello%s\n", token);
        }

      fclose (file);
      //getdelim (char ** lineptr, size_t *n, int delimiter, FILE * stream);

    #+END_SRC

    #+RESULTS:

- I could use a combo of strtok and getline
  - copy each line into a const char * and pass it to strtok
** write dummy C compiler that looks for simple problems in C files.
** copying SIZE bytes from one array to another

#+HEADERS: :includes <stdio.h> <string.h>
#+BEGIN_SRC C :dir ~/programming/c/

char string [16] = "hello World\0";
char other_string [16];

memcpy (other_string, string, 7);

fwrite (other_string, 1, 7, stdout);

#+END_SRC

#+RESULTS:
: hello W

* more ways to learn C
** The 5 things I could try to learn C faster
https://www.cprogramming.com/how_to_learn_to_program.html
** man pages provide C code examples!  Check out "man getdelim"
** learning how to code https://www.cprogramming.com/how_to_learn_to_program.html
** c reference library http://en.cppreference.com/w/
** c function reference https://www.cprogramming.com/function.html
** c understanding compiler errors https://www.cprogramming.com/tutorial/compiler_linker_errors.html
** learning how to debug C code https://www.cprogramming.com/debugging/segfaults.html
** C programming forum https://cboard.cprogramming.com/cplusplus-programming/69086-parsing-html-files.html
* simple C programs
** temperature

*** temperature printing and integer truncating
     #+HEADERS: :includes <stdio.h>
     #+BEGIN_SRC C
       int main ()
       {
         int fahr, celsius;
         int lower, upper, step;

         lower = 0;                    /* lower limit of temperature table */
         upper = 300;                  /* upper limit */
         step = 20;                    /* step size */

         fahr = lower;
         printf ("Fahrenheit Celsius\n");
         while (fahr <= upper)
           {
             celsius = 5 * (fahr - 30) / 9;
             //celsius = (fahr - 30) * (5/9);  //this is wrong
             //in C integer division, truncates any remainder
             // aka  5 / 9 = .55555, but in C  5/9 == 0
             printf ("%d %d\n", fahr, celsius);
             fahr = fahr + step;
           }
         return 0;
       }
     #+END_SRC

     #+RESULTS:
     | Fahrenheit | Celsius |
     |          0 |     -16 |
     |         20 |      -5 |
     |         40 |       5 |
     |         60 |      16 |
     |         80 |      27 |
     |        100 |      38 |
     |        120 |      50 |
     |        140 |      61 |
     |        160 |      72 |
     |        180 |      83 |
     |        200 |      94 |
     |        220 |     105 |
     |        240 |     116 |
     |        260 |     127 |
     |        280 |     138 |
     |        300 |     150 |
*** temperature conversion more accurate

#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C

  int main ()
  {
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;
    upper = 300;
    step = 10;

    fahr = lower;
    printf ("Fahrenheit Celsius\n");
    while (fahr <= upper)
      {
        /* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
        celsius = (5.0 / 9.0) * (fahr - 32.0);
        /* 3.0, means print at least 3 characters wide with no decimal digit */
        /* 6.1 means print at least 8 characters wide with 3 decimal digits */
        printf ("%3.0f %8.3f\n", fahr, celsius);
        fahr = fahr + step;
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
| Fahrenheit | Celsius |
|          0 | -17.778 |
|         10 | -12.222 |
|         20 |  -6.667 |
|         30 |  -1.111 |
|         40 |   4.444 |
|         50 |    10.0 |
|         60 |  15.556 |
|         70 |  21.111 |
|         80 |  26.667 |
|         90 |  32.222 |
|        100 |  37.778 |
|        110 |  43.333 |
|        120 |  48.889 |
|        130 |  54.444 |
|        140 |    60.0 |
|        150 |  65.556 |
|        160 |  71.111 |
|        170 |  76.667 |
|        180 |  82.222 |
|        190 |  87.778 |
|        200 |  93.333 |
|        210 |  98.889 |
|        220 | 104.444 |
|        230 |   110.0 |
|        240 | 115.556 |
|        250 | 121.111 |
|        260 | 126.667 |
|        270 | 132.222 |
|        280 | 137.778 |
|        290 | 143.333 |
|        300 | 148.889 |
*** temperature conversion more accurate celsius --> fahrenheit

#+HEADERS: :includes <stdio.h>
#+BEGIN_SRC C

  int main ()
  {
    float fahr, celsius;
    int lower, upper, step;

    lower = 0;
    upper = 300;
    step = 10;

    celsius = lower;
    printf ("Celsius Fahrenheit\n");
    while (celsius <= upper)
      {
        /* 5.0 / 9.0 is not truncated to 0, because 5.0 is a floating number not an int */
        fahr = (5.0 / 9.0) * celsius + 32;
        /* 3.0, means print at least 3 characters wide with no decimal digit */
        /* 6.1 means print at least 8 characters wide with 3 decimal digits */
        printf ("%3.0f %5.1f\n", celsius, fahr);
        celsius = celsius + step;
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
| Celsius | Fahrenheit |
|       0 |       32.0 |
|      10 |       37.6 |
|      20 |       43.1 |
|      30 |       48.7 |
|      40 |       54.2 |
|      50 |       59.8 |
|      60 |       65.3 |
|      70 |       70.9 |
|      80 |       76.4 |
|      90 |       82.0 |
|     100 |       87.6 |
|     110 |       93.1 |
|     120 |       98.7 |
|     130 |      104.2 |
|     140 |      109.8 |
|     150 |      115.3 |
|     160 |      120.9 |
|     170 |      126.4 |
|     180 |      132.0 |
|     190 |      137.6 |
|     200 |      143.1 |
|     210 |      148.7 |
|     220 |      154.2 |
|     230 |      159.8 |
|     240 |      165.3 |
|     250 |      170.9 |
|     260 |      176.4 |
|     270 |      182.0 |
|     280 |      187.6 |
|     290 |      193.1 |
|     300 |      198.7 |
*** temperature via for loop

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    int fahr;

    for (fahr = 0; fahr <= 300; fahr = fahr + 20)
      {
        printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
|   0 | -17.8 |
|  20 |  -6.7 |
|  40 |   4.4 |
|  60 |  15.6 |
|  80 |  26.7 |
| 100 |  37.8 |
| 120 |  48.9 |
| 140 |  60.0 |
| 160 |  71.1 |
| 180 |  82.2 |
| 200 |  93.3 |
| 220 | 104.4 |
| 240 | 115.6 |
| 260 | 126.7 |
| 280 | 137.8 |
| 300 | 148.9 |
*** temperature via for loop with constants

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  #include <stdio.h>

  #define LOWER 0
  #define UPPER 300
  #define STEP 20

  int main ()
  {
    int fahr;

    for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)
      {
        printf ("%d %6.1f\n", fahr, (5.0/9.0) * (fahr - 32));
      }
    return 0;
  }
#+END_SRC

#+RESULTS:
|   0 | -17.8 |
|  20 |  -6.7 |
|  40 |   4.4 |
|  60 |  15.6 |
|  80 |  26.7 |
| 100 |  37.8 |
| 120 |  48.9 |
| 140 |  60.0 |
| 160 |  71.1 |
| 180 |  82.2 |
| 200 |  93.3 |
| 220 | 104.4 |
| 240 | 115.6 |
| 260 | 126.7 |
| 280 | 137.8 |
| 300 | 148.9 |
** printing chars
*** what's wrong with this code?

A program that outputs it's input
#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C

  char c;

  c = getchar ();
  while (c != EOF)
    {
      putchar (c);
      c = getchar ();
    }

#+END_SRC

#+RESULTS:

char c;  That's the problem.  char c can only hold 128 characters.  It is not large enough to hold the EOF character.  So c must be declared in int.
*** simpler version

#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    int c;

    while ((c = getchar()) != EOF)
      putchar (c);

    return 0;
  }
#+END_SRC

#+RESULTS:
*** program to print value of EOF

#+BEGIN_SRC C
  #include <stdio.h>

  int main ()
  {
    printf("%d\n", EOF);
    return 0;
  }

#+END_SRC

#+RESULTS:
: -1
*** counting lines

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  int main ()
  {

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nl;

    nl = 0;

    while ((c = fgetc(stream)) != EOF)
      if (c == '\n')
        ++nl;

    printf ("number of lines in %s is %d\n", string, nl);

    return 0;
  }
#+END_SRC

#+RESULTS:
: number of lines in silly.txt is 9
*** counting lines, blanks, tabs

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  int main ()
  {

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nl, tabs, blanks = 0;

    while ((c = fgetc(stream)) != EOF)
      switch (c)
        {
        case '\n':
          ++nl;
          break;

        case '\t':
          ++tabs;
          break;

        case ' ':
          ++blanks;
          break;
        }
    printf ("number of lines in %s is %d\n", string, nl);
    printf ("number of blanks in %s is %d\n", string, blanks);
    printf ("number of tabs in %s is %d\n", string, tabs);

    return 0;
  }
#+END_SRC

#+RESULTS:
| number | of | lines  | in | silly.txt | is |  9 |
| number | of | blanks | in | silly.txt | is | 16 |
| number | of | tabs   | in | silly.txt | is |  0 |
*** counting words and characters  there's something wrong here

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
   #include <stdio.h>

   #define IN  1
   #define OUT 0

   int main ()
   {

     char string [16] = "silly.txt";

     FILE * stream = fopen (string, "r");

     int c, nc, nl, nw, state = 0;

     while ((c = fgetc (stream)) != EOF)
       {
         ++nc;
         if (c == '\n')
           ++nl;

         if (c == '\n' || c == ' ' || c == '\t')
           state = OUT;
         else
           {
             if (state == OUT)
               state = IN;
             ++nw;
           }
       }

     printf ("%s has %d lines, %d words, and %d characters\n", string, nl, nw, nc);

     return 0;
   }
#+END_SRC

#+RESULTS:
| silly.txt has 9 lines | 32934 words | and 193 characters |

*** print a file with each word on each line

#+BEGIN_SRC C  :dir ~/manuals/cheatsheets/text-files/  :includes <stdio.h>  :defines OUT 0 IN 1

    char string [16] = "silly.txt";

    FILE * stream = fopen (string, "r");

    int c, nc, nl, nw, state = 0;

    while ((c = fgetc (stream)) != EOF)
      {
        if (c == ' ')
          {
            state = OUT;
            printf("\n");
          }
        else
          {
            if (state == OUT)
              state = IN;
            fputc (c, stdout);
            state = IN;
            ++nw;
          }
      }
#+END_SRC

#+RESULTS:
| #+AUTHOR:Joshua          |
| Branson                  |
| #+TITLE:                 |
| #+LATEX_HEADER:          |
| \usepackage{lmodern}     |
| #+LATEX_HEADER:          |
| \usepackage[QX]{fontenc} |
| #+OPTIONS:               |
| H:10                     |
| toc:nil                  |
|                          |
| *                        |
| This                     |
| is                       |
| a                        |
| silly                    |
| Text                     |
| File                     |
|                          |
| I'm                      |
| using                    |
| it                       |
| to                       |
| count                    |
| lines                    |
|                          |
| to                       |
| to                       |
| to                       |
*** print a histogram of the length of words in a file what's wrong here?

#+BEGIN_SRC C   :dir ~/manuals/cheatsheets/text-files/
  #include <stdio.h>

  #define IN  1
  #define OUT 0
  #define MAX_WORD_LENGTH  32

  int main ()
  {

    char string [16] = "silly.txt";
    /* word_length[5] = 7, means that there were 7 words of length 5; */
    int word_lengths [MAX_WORD_LENGTH];

    /* initialize word_lengths to 0 */
    for (int i = 0; i < MAX_WORD_LENGTH; i++)
      word_lengths[i] = 0;

    FILE * stream = fopen (string, "r");

    /* nw == new word */
    /* wl == word length */
    int c, nw, wl, state = 0;

    while ((c = fgetc (stream)) != EOF)
      {
        /* if this is NOT a word, state is now OUT of word */
        if (c == '\n' || c == ' ' || c == '\t')
          {
            state = OUT;
            if (wl > 0)
              {
                word_lengths[wl] = word_lengths[wl] + 1;
              }
            wl = 0;
          }
        else //state is now IN a word
          {
            if (state == OUT)
              {
                state = IN;
                ++nw;
              }
            ++wl;
          }
      }

    printf ("%s has %d words\n", string, nw);

    //print the histogram of word lengths
    //ie:
    /* word_lengths = {0, 1, 4, 5}
       output is :

       1 -
       2 ----
       3 -----
    ,*/

    for (int i = 1; i < MAX_WORD_LENGTH; i++)
      {
        if (word_lengths[i])
          {
            printf("%d ", i);
            for (int j = 0; j < word_lengths[i]; j++)
              fputc ('-', stdout);
            printf("\n");
          }
      }

    return 0;
  }
#+END_SRC

#+RESULTS:
** write a C program to determine the size of float, double, and long double.

The headers <limits.h> and <float.h> should be helpful to do this.
** Bitwise programs
*** Turning off the lower 7 bits of a number

#+BEGIN_SRC C  :includes <stdio.h>
  int b = 0b111111111111;

  printf("%d %d %d\n", b, 0177, b & 0177);

  int c = 0b111110000000;

  printf("%d %u\n", c, c);
#+END_SRC

#+RESULTS:
| 4095 |  127 | 127 |
| 3968 | 3968 |     |
** write a program to use alloc [[info:libc#Variable%20Size%20Automatic][info:libc#Variable Size Automatic]]
** make a C function to print a decimal number in binary

#+BEGIN_SRC C :includes '("<stdio.h>" "<math.h>") :flags -lm :defines MAX_NUMBER 128

  /* This function takes an int and prints its binary representation */
  int return_highest_power_of_2 (int i)
  {
    /* find the highest power of 2 <= i */
    short int n = 0;
    for (; pow(2 , n) <= i; ++n)
    {

    }
    return --n;
  }

  int * return_b_number (int n)
  {
    if (n == 0)
      {
        return 0;
      }
    if (n == 1)
      {
        return 1;
      }
    short highest_power_of_2 = return_highest_power_of_2 (n);
    //this needs to be turned into something interesting...
    return return_b_number (n - pow(2, highest_power_of_2)) + pow (2, highest_power_of_2);
  }

  print_b_number (int n)
  {
    //printf("%d\n", return_b_number (n));
  }

  int main ()
  {
    //print_b_number (2);
    //printf ("%d\n", return_highest_power_of_2 (32));
    printf ("%3.0f\n", return_b_number (2));
    printf ("%d\n", (int) return_b_number (2));
    return 0;
  }
#+END_SRC

#+RESULTS:
** What is using strcat is bad idea?

:ANSWER:
strcat concatenates two strings.  It is a bad idea, but strcat is a slow method of concatenating two strings.
C does not store the length of strings.  Instead, it has to calculate the length of the strings each time, one
attempts to copy a string.

It may be a better idea to use mempcpy.
:END:

** messing with arrays
Ok, so org-babel should be throwing an error here, but it is not...
#+BEGIN_SRC C  :includes <stdio.h>
int a [8];
a[7] = 3;
a[6] = 4;
a[55] = 1;
a[0] = 2;
printf ("%d %d %d %d\n", a[7], a[6], a[8], a[0]);
#+END_SRC

#+RESULTS:
: 3 4 4195952 2
** highest power of 2

#+BEGIN_SRC C  :includes '("<math.h>" "<stdio.h>")  :flags -lm
  int return_highest_power_of_2 (int i)
  {
    /* find the highest power of 2 <= i */
    short int n = 0;
    for (; pow(2 , n) <= i; ++n)
      {

      }
    return --n;
  }

  int main ()
  {
    short a = return_highest_power_of_2 (0);
    short b = return_highest_power_of_2 (1);
    short c = return_highest_power_of_2 (2);
    short d = return_highest_power_of_2 (3);
    short e = return_highest_power_of_2 (4);
    short f = return_highest_power_of_2 (5);
    short g = return_highest_power_of_2 (6);
    short h = return_highest_power_of_2 (8);
    short i = return_highest_power_of_2 (9);
    short j = return_highest_power_of_2 (10);
    short k = return_highest_power_of_2 (11);
    short l = return_highest_power_of_2 (16);

    printf ("0 %d\n", a);
    printf ("1 %d\n", b);
    printf ("2 %d\n", c);
    printf ("3 %d\n", d);
    printf ("4 %d\n", e);
    printf ("5 %d\n", f);
    printf ("6 %d\n", g);
    printf ("8 %d\n", h);
    printf ("9 %d\n", i);
    printf ("10 %d\n", j);
    printf ("11 %d\n", k);
    printf ("16 %d\n", l);

    return 0;
  }
#+END_SRC

#+RESULTS:
|  0 | -1 |
|  1 |  0 |
|  2 |  1 |
|  3 |  1 |
|  4 |  2 |
|  5 |  2 |
|  6 |  2 |
|  8 |  3 |
|  9 |  3 |
| 10 |  3 |
| 11 |  3 |
| 16 |  4 |
** programs with IPC
All of these things are discussed in the libc manual.
*** sockets
*** PIPES & FIFOs
*** Threads
*** Processes
*** Signals
*** controlling paging
** syslog
** caesar cipher and decrypt program

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "Probably the simplest case is to decrypt a short sentence." | ./caesar -s 1 | ./caesar -s 25
#+END_SRC

#+RESULTS:
: Probably the simplest case is to decrypt a short sentence.

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "GNU Emacs is Free" | ./caesar -s 1
#+END_SRC

#+RESULTS:
: HOV Fnbdt jt Gsff

#+BEGIN_SRC sh :results output :exports both :dir ~/prog/c/caesar/src/
  echo "GNU Emacs is Free" | ./caesar -s 1 | ./decrypt
#+END_SRC

#+RESULTS:
: GNU Emacs is Free

* C bitwise operators
** Bitwise &

The & operator takes two integers, and outputs the bits that are both 1.

|------+---+------|
|   13 | & |   11 |
| 1111 |   | 1100 |
|------+---+------|

Now the bitwise & operation

| 13 | 1101 |
| 11 | 1011 |
|  & |    & |
|----+------|
|  9 | 1001 |

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a, b;
    a = 13;
    b = 11;

    printf("%d\n", a & b);

    a = 0b1101;  //binary 13
    b = 0b1101;  //binary 11

    return 0;
  }

#+END_SRC

#+RESULTS:
: 9
** Bitwise OR |

Bitwise OR is like the propositional logic "\/".

For two binary numbers, the if one bit is a 1, then the answer will have a 1.

|   15 | OR |  3 |
| 1111 |    | 11 |

| 15 | 1111 |
| 13 | 0011 |
| OR |   OR |
|----+------|
| 15 | 1111 |

#+HEADERS :includes  <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a = 15;
    int b = 13;

    printf("%d\n", a|b);

    a = 0b1111;
    b = 0b1101;

    printf("%d\n", a|b);

    return 0;
  }
#+END_SRC

#+RESULTS:
| 15 |
| 15 |
** Bitwise Exclusive OR   XOR   ^

|   17 | OR |    9 |
| 1111 |    | 1001 |

| 17 | 10001 |
|  9 | 01001 |
|  ^ |     ^ |
|----+-------|
| 25 | 11000 |

#+HEADERS :includes  <stdio.h>
#+BEGIN_SRC C
  int main ()
  {
    int a = 17;
    int b = 9;

    printf("%d\n", a|b);

    a = 0b10001;
    b = 0b1001;

    printf("%d\n", a|b);

    return 0;
  }
#+END_SRC

#+RESULTS:
| 25 |
| 25 |
** Bitwise complement Operator  ~

I don't understand this one.  I thought ~13 = 2.

It only works on one operand.  It inverts all bits of one number to the opposite bit.

|  13 | 1101 |
|   ~ |    ~ |
|-----+------|
| -14 | 0010 |   ?????

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
    int main ()
    {
      int i = 13;

      printf("%d\n", ~i);

      i = 0b1101;
      printf("%d\n", ~i);

      return 0;
    }
#+END_SRC

#+RESULTS:
| -14 |
| -14 |
** Shift operators  <<  and   >>

|   1 | <<2 | 1 | <<2 |
|-----+-----+---+-----|
| 100 |     | 4 |     |

The left shift operator moves bits in a number to the left.

#+HEADERS :includes <stdio.h>
#+BEGIN_SRC C
    int main ()
    {
      int a = 1;
      int b = 0b1;

      printf("%d %d\n", a<<2, b<<2);

      return 0;
    }
#+END_SRC

#+RESULTS:
: 4 4
* The autoconf manual has some examples of buffer overflow and null pointers

[[info:autoconf#Portable%20C%20and%20C++][info:autoconf#Portable C and C++]]


code:
#+AUTHOR:Joshua Branson
#+TITLE: Let's Encrypt & Certbot
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}
#+OPTIONS: H:10 toc:nil

* Let's Encrypt & Certbot

All websites should be encrypted using https!  Many are not.  If you
are not encrypting our websites, then users data can be leaked to
anyone.  If you would like your website to appear high on Google's
search results, and you care about user privacy online, then you
should try "Let's Encrypt".  Let's Encrypt is a free certificate
authority, and everybody should use it!

In order to start using let's encrypt, you need to prove to the "Let's
Encrypt" people that you actually own your website.  "Certbot" is a
program that will help you do this.  Certbot can generate a
certificate for you, and create a secret file on your webserver.
Certbot then will navigate to that file to check that you actually own
the website.  Then your certificate will work.

You will also have to automatically renew your certificates.  Certbot
can periodically renew your certificates for you.

As of [2018-04-09 Mon], the nginx plugin to certbot does not support
confirming that I control a domain.  For example, when I try to do
that I get this error:

#+BEGIN_SRC sh :results output :exports both :dir /ssh:root@richardrahl:/var/www/html/gnucode.me/public_html/
sudo certbot --nginx -d gnucode.me -d www.gnucode.me
#+END_SRC

#+RESULTS:
sudo: unable to resolve host RichardRahl
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.
Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.

So I have to use the webroot command.  This command can be an authenticator and an installer?

certbot [subcommand] [options]

** Vocab

- authenticators

  Authenticators verify that you can change content on your website.  The subcommand certonly is an authenticator.

  Authenticators install the certificate, confirms that you own your domain, but does not edit your nginx or apache's files.  Certbot can issue a single certificate to use for all of your domains, but you need to specify all of the domains.

  It installs the certificate in the /etc/letsencrypt/ directory.  You could use a symlink to point to the certificate.

- installers
  Installers are plugins that use the install command to modify your nginx config file to serve the certificate.

** Installing certbot on an nginx server when the nginx plugin doesn't work:

This authenticates two domains:  gnusites.com and gnucode.me

sudo certbot certonly --webroot -w /var/www/html/gnusites.com/public_html/ -d www.gnusites.com -d gnusites.com -w /var/www/html/gnucode.me/public_html/ -d www.gnucode.me -d gnucode.me

The output of the command tells me:

sudo: unable to resolve host richardrahl
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for www.gnusites.com
http-01 challenge for gnusites.com
http-01 challenge for www.gnucode.me
http-01 challenge for gnucode.me
Using the webroot path /var/www/html/gnucode.me/public_html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/www.gnusites.com/fullchain.pem. Your cert
   will expire on 2018-07-08. To obtain a new or tweaked version of
   this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

It should have created a temporary file at ${webroot-path}/.well-known/acme-challenge

Nginx tells me that gnusites.com/.well-known/acme-challenge does not exist.

Wordpress tells me that gnucode.me/.well-known/acme-challenge cannot be found.

The command tells me that it challenged www.gnusites.com, gnusite.com, gnucode.me, and www.gnucode.me.

** Trying out the certificate

I'm getting weird errors.  Gnusites is encrypted, but https://gnucode.me is serving gnusites...?

gnusites.com works just fine.

Here is the code that I pulled from this online tutorial:  https://www.nginx.com/blog/using-free-ssltls-certificates-from-lets-encrypt-with-nginx/

#+BEGIN_SRC sh :results output :exports both :dir /ssh:joshua@richardrahl:/var/www/html/gnucode.me/public_html/
grep "RSA"  -A 10   /etc/nginx/sites-enabled/gnusites.com
#+END_SRC

#+RESULTS:
#+begin_example
    # RSA certificate
    ssl_certificate /etc/letsencrypt/live/www.gnusites.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.gnusites.com/privkey.pem; # managed by Certbot

    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot

    # Redirect non-https traffic to https
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    } # managed by Certbot

#+end_example

* setting up certbot for laundrysucks io

joshua@richardrahl:/var/www/html/laundrysucks.io/public_html$ sudo certbot certonly --webroot -w /var/www/html/laundrysucks.io/public_html/ -d laundrysucks.io
sudo: unable to resolve host richardrahl
[sudo] password for joshua:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for laundrysucks.io
Using the webroot path /var/www/html/laundrysucks.io/public_html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0002_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0002_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/laundrysucks.io/fullchain.pem. Your cert will
   expire on 2018-08-18. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

* setting up certbot for gnu-hurd.com

joshua@richardrahl:/var/www/html/gnu-hurd.com/.well-known$ sudo certbot certonly --webroot -w /var/www/html/gnu-hurd.com/public_html/ -d gnu-hurd.com -d www.gnu-hurd.com
sudo: unable to resolve host richardrahl
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for gnu-hurd.com
http-01 challenge for www.gnu-hurd.com
Using the webroot path /var/www/html/gnu-hurd.com/public_html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0003_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0003_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/gnu-hurd.com/fullchain.pem. Your cert will
   expire on 2018-08-19. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

* online manual https://certbot.eff.org/docs/using.html

#+BEGIN_SRC sh :results output :exports both :dir /ssh:joshua@richardrahl:/home/joshua
ls
#+END_SRC

#+RESULTS:
: dead.letter  grep

#+BEGIN_SRC sh :results output :exports both :dir /ssh:joshua@richardrahl:/home/joshua
cat grep
#+END_SRC

#+RESULTS:

#+BEGIN_SRC sh :results output :exports both :dir /ssh:joshua@richardrahl:/home/joshua
rm grep
#+END_SRC

#+RESULTS:

#+BEGIN_SRC sh :results output :exports both :dir /ssh:joshua@richardrahl:/home/joshua
ls
#+END_SRC

#+RESULTS:
: dead.letter
* webroot

This gets a certificate for a website the specific spot you have
certbot certonly --webroot -w /var/www/html/matomo/public_html -d www.gnucode.me -d gnucode.me
* revoking a certificate

=certbot revoke --cert-path  /path/to/certificate=
* adding a domain to a certificate.

This command expands a certificate to include a new domain name.  existing.com and www.existing.com were domains that the certificate already had.  But I added the two domains: blog.existing.com and www.blog.existing.com.
=certbot --cert-name existing.com -d existing.com,www.existing.com,blog.existing.com,www.blog.existing.com=

repo_name: hwpplayers/cheatsheets

license: mit


code:
#+TITLE: Core Utilities Cheat Sheet
#+AUTHOR: Joshua Branson

* Common Options
** source of randon data
/dev/random and /dev/urandom can be used as the random number generator
--random-source=FILE

** Traversing Symbolic links
chown, chgrp, and chmod all accept -R  or the recursive option, which means do this command for all directories
underneath what this command specifies

#+BEGIN_SRC sh
ls ~/Documents/
#+END_SRC

#+RESULTS:

#+BEGIN_SRC sh
chown joshua ~/documents/
#+END_SRC

* find
  - find and report all php files in the specified dir current directory

    #+BEGIN_SRC sh :dir ~/programming/waypoint/nutripledge/
    find . -name '.*php' -print
    #+END_SRC

    #+RESULTS:
    | ./calendar1/__MACOSX/supercali-1.0.8/._modules.php                    |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._week.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._year.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._upcoming.php           |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._grid.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._weeklist.php           |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._day_week_functions.php |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._quarter.php            |
    | ./calendar1/__MACOSX/supercali-1.0.8/modules/._day.php                |
    | ./calendar1/__MACOSX/supercali-1.0.8/._edit_users.php                 |
    | ./calendar1/__MACOSX/supercali-1.0.8/._delete_event.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/._admin_actions.php              |
    | ./calendar1/__MACOSX/supercali-1.0.8/._edit_links.php                 |
    | ./calendar1/__MACOSX/supercali-1.0.8/._bad_password.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/._login.php                      |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._notify.php            |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._session_start.php     |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._nav.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._start.php             |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._footer.php            |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._top_nav.php           |
    | ./calendar1/__MACOSX/supercali-1.0.8/includes/._hidden_fields.php     |
    | ./calendar1/__MACOSX/supercali-1.0.8/._edit_categories.php            |
    | ./calendar1/__MACOSX/supercali-1.0.8/._upload_events.php              |
    | ./calendar1/__MACOSX/supercali-1.0.8/._edit_groups.php                |
    | ./calendar1/__MACOSX/supercali-1.0.8/._edit_event.php                 |
    | ./calendar1/__MACOSX/supercali-1.0.8/._user_profile.php               |
    | ./calendar1/__MACOSX/supercali-1.0.8/lang/._en_us.php                 |

** To find all of the specified files in all of the subdirectories starting with dir
    #+BEGIN_SRC sh :dir ~/programming/waypoint/henriott-group/
    find . -name \*.php -print
    #+END_SRC

    #+RESULTS:
    | ./.#b3.php                    |
    | ./history.php                 |
    | ./staff.php                   |
    | ./p7.php                      |
    | ./about.php                   |
    | ./p5.php                      |
    | ./talk.php                    |
    | ./b3.php                      |
    | ./industries.php              |
    | ./account.php                 |
    | ./industry-pictures.php       |
    | ./2.php                       |
    | ./css/connect-to-database.php |
    | ./contact.php                 |
    | ./b4.php                      |
    | ./includes/footer.php         |
    | ./includes/nav.php            |
    | ./includes/header.php         |
    | ./products.php                |

    To find all of the selected files (including sub-directories) and then delete them

  #+BEGIN_SRC sh :dir ~/programming/waypoint/nutripledge/
   find . -name \*.pdf -exec /bin/rm {} \;
   #+END_SRC

  #+RESULTS:

** finding multiple file names

#+BEGIN_SRC sh :results output :exports both :dir ~programming/gnu/hurd/hurd-web/
find . -name '*png' -o -name '*svg' -o -name '*jpg'
#+END_SRC

#+RESULTS:
| ./donate/foss_factory/logo.png |
| ./hurd/status/hurd-fvwm-screenshot-2009-11-12.png |
| ./hurd/status/hurd-iceweasel-screenshot-2012-03-21.png |
| ./logo/boxes-redrawn.png |
| ./logo/boxes-redrawn.svg |
| ./microkernel/OS-structure.svg |
| ./open_issues/c42ea6c9-f574-4b33-8440-f846b05856de.png |
| ./unsorted/FunnyHurd/HurdCarDeal.jpg |
| ./unsorted/FunnyHurd/HurdMagician.jpg |
| ./unsorted/GrantBowHurdPage/diagram.png |
| ./unsorted/JoachimNilssonHurdPage/patch_kit.jpg |
| ./unsorted/SeenHurd/lmf10_1999.jpg |
| ./unsorted/TestWebMenu/lmf09_1999.jpg |
| ./unsorted/WebHome/hurd_sm_mf.png |
| ./user/jkoenig/gsoc2011_classes.png |

* grep/egrep/fgrep
grep searching a list of file/s for a pattern and outputs the matching lines.  Grep only supports a handful of regular expressions.  If you want to use ALL of the regexp expression goodies, you need to use egrep.  fgrep is fast grep.  It interprets the string as a literal string and not a regexp.

There is no way to match newline characters with grep.  [[info:grep#Introduction][info:grep#Introduction]]
  #+BEGIN_SRC
  grep OPTIONS PATTERN [INPUT_FILE_NAMES | - ]
  #+END_SRC

  The "-" for grep means standard input.

  ie:

  #+BEGIN_SRC sh :dir ~/
  grep -rc th | grep -m 5 Sass -
  #+END_SRC

  #+RESULTS:
  | .gem/ruby/2.3.0/doc/sass-3.4.21/ri/Sass/Tree/MediaNode/value-i.ri:1          |
  | .gem/ruby/2.3.0/doc/sass-3.4.21/ri/Sass/Tree/MediaNode/resolved_value-i.ri:1 |
  | .gem/ruby/2.3.0/doc/sass-3.4.21/ri/Sass/Tree/MediaNode/new-c.ri:1            |
  | .gem/ruby/2.3.0/doc/sass-3.4.21/ri/Sass/Tree/MediaNode/name-i.ri:1           |
  | .gem/ruby/2.3.0/doc/sass-3.4.21/ri/Sass/Tree/MediaNode/query-i.ri:1          |

  If you want to search for a regexp in the current directory and all sub-directories

  #+BEGIN_SRC
  grep -lr "<PATTERN>"
  #+END_SRC

  command options

** -e PATTERN
lets you specify a pattern by regexp, and you can specify multiple patters!
#+BEGIN_SRC sh :dir ~/  :results output
  grep -e be -e lint unofficial-packages.txt
#+END_SRC

#+RESULTS:
: bemenu-git r223.c3abc43-1
: csslint 0.10.0-1

So I can see "be"menu and css"lint", but you could do the same thing with

#+BEGIN_SRC sh :dir ~/ :results output
egrep "be|lint" unofficial-packages.txt
#+END_SRC

#+RESULTS:
: bemenu-git r223.c3abc43-1
: csslint 0.10.0-1

Note that the e flag should be given last on the flag list.  If it is given first, then the rest of your flags
will be thought of as the argument.  ie:

#+BEGIN_SRC sh :dir ~/ :results output
  grep -ei -
#+END_SRC

** -r search recursively, ignore symlinks
-R searches recursively following all symlinks
*** --exclude-dir=GLOB
exclude any dirs that match the GLOB
The GLOB can use "?,*[...]" to match.  I don't believe that you can use a regexp expression though
*** --exclude-file=GLOB
exclude any files that match the pattern.
The GLOB can use "?,*[...]" to match.  I don't believe that you can use a regexp expression though
*** --include=GLOB
include any files that match the pattern.
The GLOB can use "?,*[...]" to match.  I don't believe that you can use a regexp expression though
** -i ignore case

This lets you say that you want to ignore case in your grep search

#+BEGIN_SRC sh :dir ~/documents :results output
grep -i soups cooking.org
#+END_SRC

#+RESULTS:
: * Soups
: ** Do not push cut garlic into soups. EVER.

You can see that it changed my pattern into [Ss]oups

** -w word regexp

#+BEGIN_SRC sh :dir ~/documents :results output
grep -i soup cooking.org
#+END_SRC

#+RESULTS:
: * Soups
: ** Do not push cut garlic into soups. EVER.
:    You will ruin the soup.  It will be way too garlicky!

Suppose that we do not only the word "soup" and not to match "soups." or "Soups".  We could do this:

#+BEGIN_SRC sh :dir ~/documents :results output
grep -i "\bsoup\b" cooking.org
#+END_SRC

#+RESULTS:
:    You will ruin the soup.  It will be way too garlicky!

or to save some time, we could do this:

#+BEGIN_SRC sh :dir ~/documents :results output
grep -iw soup cooking.org
#+END_SRC

#+RESULTS:
:    You will ruin the soup.  It will be way too garlicky!

** -x line regexp

This just says that the regexp should match the whole line.  So it's like saying "^" PATTERN "$"
** -c count matching lines
output the total count the matching lines in the file

#+BEGIN_SRC sh :dir ~/manuals/ :results output
  grep -c the hurd.org
#+END_SRC

#+RESULTS:
: 2

#+BEGIN_SRC sh :dir ~/manuals/ :results output
  grep -c the pacman.org practical-gnus.org
#+END_SRC

#+RESULTS:
: pacman.org:4
: practical-gnus.org:65
** -l print files that match the pattern
** -L print files that do not match the pattern
** -m <MAX Number> stop reading a file after Max matches have been found

#+BEGIN_SRC sh :dir ~/manuals :results output
grep -nm 6 -e the pacman.org practical-gnus.org
#+END_SRC

#+RESULTS:
#+begin_example
pacman.org:15:*** Failed to commit transaction package: /path/to/file exists in the filesystem
pacman.org:21:  The problem is usually trivial to solve. A safe way is to first check if another package owns the file (pacman -Qo /path/to/file). If the file is owned by another package, file a bug report. If the file is not owned by another package, rename the file which 'exists in filesystem' and re-issue the update command. If all goes well, the file may then be removed.
pacman.org:25:  Every installed package provides a /var/lib/pacman/local/$package-$version/files file that contains metadata about this package. If this file gets corrupted, is empty or goes missing, it results in file exists in filesystem errors when trying to update the package. Such an error usually concerns only one package. Instead of manually renaming and later removing all the files that belong to the package in question, you may exceptionally run pacman -S --force $package to force pacman to overwrite these files.
pacman.org:30:[fn:1] The Official name is Arch Linux, but I prefer to call it Arch GNU/Linux, to respect the hard word that GNU put into creating the GNU/Linux operating system.  For more information, you can check out: [[https://www.gnu.org/gnu/why-gnu-linux.html%20][What's in a Name?]]  and [[https://www.gnu.org/gnu/gnu-linux-faq.html][GNU/Linux FAQ]].
practical-gnus.org:18:Copyright: This work is licensed under the [[http://creativecommons.org/licenses/by-nc-nd/3.0/][Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License]].
practical-gnus.org:23:People think it is hard because they get lost in its features. It would be much easier if they learned the *essential 5% features* and ignore the remaining 95%.
practical-gnus.org:32:- Usable when offline. Check the "offline" part in the section "Advanced tips"
practical-gnus.org:33:- powerful combined with other plugins like [[https://github.com/capitaomorte/yasnippet][yasnippet]]
practical-gnus.org:37:- "C" means "Ctrl" and "M" means "Alt". For example, "M-x" means pressing "Alt" and "X" together.
practical-gnus.org:41:- "Group buffer" means the list of folders.
#+end_example
** -A <NUM> (after)
print NUMber of lines after the match
** -B <NUM> (before)
print NUM of lines before the match
** -C <NUM> (context)
print NUM of lines before and after.
** -H with filename
** -h no filename
** egrep
egrep is extended regexp
* permissions
In Unix everything is a file.  When you write a text document called "text.text", that is a Unix file.  When you create a directory (Windows users call this a folder) called "Music",  you also are creating a Unix file.  Obviously, "text.text" and "Music" behave very differently.  One has your favorite songs, and the other is a text document, BUT the linux kernel assumes that they are both Unix files.  All unix files have read, write, and execute permissions specific to each unix file.  This typiccally means that the ordinary user joshua cannot read, write, or execute anything in the =/root/= folder.

# I found this segment online here: https://stackoverflow.com/questions/6732430/how-do-i-give-write-permission-to-file-in-linux
#+BEGIN_SRC latex
read     = 4
write    = 2
execute  = 1
owner    = read | write = 6
group    = read         = 4
other    = read         = 4
The basic syntax of the command to set the mode is

chmod 644 [file name]
In C, that would be

#include <sys/stat.h>

chmod("[file name]", 0644);
 #+END_SRC

#+RESULTS:
#+BEGIN_LaTeX
read     = 4
write    = 2
execute  = 1
owner    = read | write = 6
group    = read         = 4
other    = read         = 4
The basic syntax of the command to set the mode is

chmod 644 [file name]
In C, that would be

#include <sys/stat.h>

chmod("[file name]", 0644);
#+END_LaTeX

** chmod

chmod [-R ] <owner> [file | directory]

Change a file's modifications.  This specifies if what user, group, and if everyone else can read, write, or execute the file.

Permissions can modify the permissions of the user's, the group's and all others.

** chown

chown [-R] <owner> [file | directory]

Change the file's owner.  The file's owner is typically root or an ordinary user.

Examples include

** chgrp

chgrp [ -R ] <group> [file | directory]

Change the group that the file or directory belongs to.

* basic usage of the find command in GNU
  #+BEGIN_SRC sh
    find . -name "pattern" -print

    find . -name "this-file.*" -print

    find . -name "this-file.*txt" -print

    find . -name "this-file\.txt" -print
  #+END_SRC
* touch -amc filename updates the files timestamps
  Access
  Modify
  Change
* join

join [OPTIONS] [FILE1 | - ] [ FILE2 | - ]

A way of combining two files based on a common column.

Either file1 or file2 can be "-", which is standard input.  So that is pretty cool.
** available options

** -a FILE-NUMBER
print a line for each unpairable line.

** -i ignore case differances

** -1 FIELD_NUMBER
Join on the nth column.  For example is the following line
=this is an example line=

"an" is on the 3rd field.

** -2 FIELD_NUMBER

Join on the nth column.  For example is the following line
=this is an example line=

"example" is on the 4th field.

** JOIN in action

#+BEGIN_SRC sh :dir ~/programming/bash/txt/ :results output
join -1 1 file1.txt file2.txt
#+END_SRC

#+RESULTS:
#+begin_example
1 12 18 this is
2 11 17 an interesting
3 10 16 experiment isn't
4 9 15 it?
5 e e 2nd field match
6 7 13
7 6 12
8 5 11
9 f f 2nd field match
10 3 9
11 2 8
12 1 7
#+end_example

#+BEGIN_SRC sh :dir ~/programming/bash/txt/ :results output
join -1 2 file1.txt file2.txt
#+END_SRC

#+RESULTS:

* xargs
lets you get stdin and feed it to other programs that otherwise would not like it, allegedly

#+BEGIN_SRC sh :dir ~/documents :results output
ls *org | xargs -i echo the{}et
#+END_SRC

#+RESULTS:
#+begin_example
theaccrisoft.orget
theapache.orget
thearch.orget
theauto-complete.orget
thebash.orget
thebbdb.orget
thecore-utils.orget
thedired.orget
thedisk.de.orget
theelisp.orget
theemacs.orget
theevil-dvorak.orget
theevil.orget
thefirefox.orget
thegawk.orget
thegimp.orget
thegit.orget
thegnuplot.orget
thegnus.orget
thegpg.orget
thehurd.orget
thehurd-rpc.orget
thehurd-talk.orget
theinetutils.orget
theiptables.orget
thejavascript.orget
thejson.orget
theledger.orget
thelinux-kernel-coding-style.orget
themach-paging-interface.orget
themagit.orget
themaking-money-with-free-software.orget
theman.orget
themysql.orget
thenetworks-networking-internet-ip4-tcp-udp.orget
theorg-babel-code-block-args.orget
theorg-babel-intro.orget
theorg-babel-sql.orget
theorg.orget
thepacman.orget
thephp.orget
thepixi.orget
thepractical-gnus.orget
thesed.orget
thesql.orget
thesystemd.orget
thethundertalks.orget
thetoward-a-new-strategy-of-os-design.orget
thetranslator-primer.orget
thetranslators.orget
thewhm.orget
thewordpress.orget
#+end_example

#+BEGIN_SRC sh :dir ~/documents :results output
ls *org | xargs -n 3
#+END_SRC

#+RESULTS:
: 4yearsOfLife.org 4yearsOfLife.org.org a-certain-matchbox-member.org
: a-girl-hitting-a-man-is-hypocritical.org approaching-and-meeting-people.org cooking.org
: cover-letter.org example-latex.org gnu-assign-copyright-hurd-email-assign.org
: how-to-succeed-in-the-army.org intro-to-gnu-linux.org letter-to-dad.org
: letterToNicole.org letter-to-vincent.org libre-software-response.org
: professor-snape-rachel-sweet-bread.org references.org romance-story.org
: soihub-pages.org university-place.org why-proprietary-software-is-wrong.org

* show available disk space
* sort

sort [OPTION] [FILE]
** options
*** -f ignore case
*** -g general numeric sort
*** -h human numeric sort
This is good for sorting

50M
-10G
1.5K
*** -M month sort
*** -n numeric sort
*** -r reverse sort
*** -R random sort
*** -t SEPARATOR
use SEPARATOR as the field separator.  By default that separator is a space.  ([[info:coreutils#sort%20invocation][info:coreutils#sort invocation]])
* How I got my local apache server working again:

 For some reason, my ~/ folder had permissions =drwxrws---=

 To fix it I did

 #+BEGIN_SRC bash :exports both
 cd /home/; chmod g-s joshua; ls -lh | grep joshua

 #+END_SRC

 #+RESULTS:
 : drwxrwx--- 83 joshua http 4.0K Feb  2 08:04 joshua

The s was magically replaced with a x
* common things that you might want to do
** get a list of files with specific attributes and have grep search those files lines matching a regexp

  find . -name "*org" | grep -r "[pP]rettyhorses"


code:
* nice -n nicenumber program
* fmt file
* df tells you how much disk space you have
  df -h filename (the -h means you want the output to be human readable)
* du how large a file is
  du -h filename


code:
#+TITLE:CSS Cheatsheat
#+AUTHOR:Joshua Branson
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}

* Flexbox

Try playing this game:
http://flexboxfroggy.com/

# Much of this content comes from [[https://css-tricks.com/snippets/css/a-guide-to-flexbox/][css tricks]] https://css-tricks.com/snippets/css/a-guide-to-flexbox/

The traditional CSS layout is crusty and does not work well for responsive design.  =display:inline;= is great for vertical layouts and =display:block;= is great for horizontal layouts.  But you can't mix and match both well, nor do these designs work well when the width and height of sections of your page are dynamic.  With flexbox, one can create layouts that are designed to expand and contract depending on the device used, or as the browser page is manually adjusted.

To use flexbox, you need a parent container (flex container) and a child or children element/s.

The flex container can either be vertically or horizontally based.  You can even specify the direction that the browser draws the elements on the screen.  So not only can you specify a vertical top down layout like this:

#+BEGIN_EXAMPLE

1

2

2

#+END_EXAMPLE

 | 1 |
 | 2 |
 | 3 |

 You can also specify that the elements appear from the bottom up like this:

#+BEGIN_EXAMPLE

1

2

2

#+END_EXAMPLE

 | 3 |
 | 2 |
 | 1 |

 The same is true for horizontal layouts.  They can look like:

#+BEGIN_EXAMPLE

1

2

2

#+END_EXAMPLE

 | 1 | 2 | 3 |

 OR

#+BEGIN_EXAMPLE

1

2

2

#+END_EXAMPLE

| 3 | 2 | 1 |

* positioning
** relative positioning
** absolute positioning

When you position an element absolutely, it is fixed.  If you put an absolute positioned element inside a div, then the div cannot calculate the height of the child.

#+BEGIN_EXAMPLE

#+END_EXAMPLE

 It'll look like this:

 [[./images/abs-pos-height.png]]

 You can see that the containing div (the green box), cannot determine the height of the image.  That is why, the green div is only 30 pixels or so tall.  [fn:1]

* Footnotes

[fn:1] In actuality, it would only be 1 or 2 pixels tall, but I make it taller so you could see it.


code:
#+AUTHOR:Joshua Branson
#+TITLE: Decent Dating/MySexyBod/Sunshine
#+LATEX_HEADER: \usepackage{lmodern}
#+LATEX_HEADER: \usepackage[QX]{fontenc}
#+OPTIONS: H:10 toc:nil

* Decent Dating/MySexyBod/Sunshine

* themes
https://startbootstrap.com/template-overviews/new-age/

https://bootswatch.com/

http://themes.getbootstrap.com/preview/?theme_id=1474&show_new=

https://themes.getbootstrap.com/product/application/

getbootstrap.com/docs/4.0/

* end to end encryption

https://github.com/w3c/activitypub/issues/225

This does not mean that users are restricted to one device.

Each device would have a private key.  A user would encrypted a message with all public keys.  Then any private key could decrypt the message.

This would cause a minor problem, if a user used the service with their phone for 4 months, then started using their laptop.  The old encrypted message could not be decrypted with their laptop.

BUT we could use symmetric encryption to decrypt the messages from the phone, then send those messages to the laptop.  That would work too.

* activity pub for online dating:

https://www.w3.org/wiki/SocialCG/2018-02-28/minutes

search for dating

slide fore online dating via activity pub.
http://slides.com/evanpro/dating-on-the-open-web-7#/0/41

* social web incubator community group

https://www.w3.org/community/socialcg/

https://github.com/swicg

meeting minutes
https://www.w3.org/wiki/SocialCG

They meet every Wednesday at 11am.  Sad face.


code:
#+TITLE:Dired Cheatsheat
#+AUTHOR: Joshua Branson
#+LANGUAGE: en
#+HTML_HEAD <link rel="stylesheet" type="text/css" href="stylesheet.css" />

* Basic commands inside a dired buffer
 - % m mark files via a regexp
 - % d mark files for deletion via a regexp
 - n/p for next previous file
 - f / RET visit that file
 - v view that file in another window
 - ^ go up one directory
 - * * mark all executables
 - * / mark all directories except for .. and .
 - * s mark all the files in the current subdirectory
 - t  toggle all marks
 - % g mark all files whose contents contain regexp
 - C copy the current file
 - d flags a file for deletion
 - x delete all files flagged for deletion
 - D delete all marked files
 - R NEW RET rename the file/files.  If only one files is marked, then that file will be renamed.
   If many files are marked, then those files will be moved into a new directory that you name
 - S NEW RET make symbolic links.  If you have just specified one file, then that file will have a symbolic link
   to/from NEW.  If you mark many files, then NEW is the directory to add the symbolic link to
 - M change the mode stuff of the file.  arguments can be what chmod would want.
 - G change the group of the file/files to a new group
 - O change the owner of file/files
 - Z compress / uncompress file/files
 - :d decrypt the file
 - :e encrypt the file
 - :s sign the file
 - :verify the sig of the file
 - B byte compile the emacs lisp file/files
 - ! runs a shell command on the file/files
 - & runs a shell command on the file/files in the background
 - % R/C/H/S TO RET FROM these 4 commands rename/copy/hard/soft links out of regexp
   What matches in TO will get replaced in from.  So to rename all files from .*php to .*phtml
   you could say % m RET php RET % R php RET phtml.  You are also free to use \& and \DIGIT
   in your FROM regexp.
 - + create a new directory
 - i displays the files in the current subdirectory w/o evoking dired on that directory
   C-u C-SPC moves point back to where you started
 - >/< move forward and backward to the previous/next subdirectory lines
 - g redisplays the dired buffer
 - C-t d toggle displaying an image
 - image-dired opens up dired to display images
 - w yanks the marked files.  Apparently this lets you yank those files into other emacs commands
 - ( toggles showing the file permissions