Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Thursday, June 4, 2015

Write a function that subtract two integer streams


You are given two streams 's_a' and 's_b' of digits. Each stream represents an integer 'a' and 'b' from its less significant digit to the most significant digit.
For example, integer 2048 is represented in the stream as 8, 4, 0, 2. 

Write a function that subtract two integers 'a - b' and returns the result as a string. You are not allowed to buffer entire 'a' or 'b' into a single string, i.e. you may access only a single digit per stream at time (imagine that 'a' and 'b' are stored in huge files). You may assume that 'a>=b'.

#include <stdio.h>

/* Subtracts two single digits, prints the reminder and returns 1(carry) if a<b */
int subtract(char c_a, char c_b)
{
  /* Convert the char to interger */
  int i_a = c_a - '0';
  int i_b = c_b - '0';
  int ret = 0;

  /* If a<b, increase 'a' by 10 and return 1(carry) to subtract it from 'a' of the next set */
  if (i_a < i_b) {
    i_a += 10;
    ret = 1;
  }
  
  printf ("%d", i_a - i_b);

  return ret;
}


int main(int agrc, char **argv)
{
  /* Get the two operand streams from input arguments */
  char *s_a = argv[1];
  char *s_b = argv[2];

  int carry_one = 0;
  
  /* Pass one char at a time from each input arguments to function subtract */
  while(*s_b != '\0'){
    /* Subtract carry_one from first operand before sending it to function subtract */
    carry_one = subtract(*s_a - carry_one, *s_b);
    s_a++;
    s_b++;
  }

  /* Print the remining digits from the first operand */
  while(*s_a != '\0'){
    printf("%c", *s_a - carry_one);
    s_a++;
    carry_one = 0;
  }
  printf("\n");
  
  return 0;
}
Output:
  $ ./str_subtract 00051 1005 | rev
  09999
  
  $ ./str_subtract 5 3 | rev
  2
  
  $ ./str_subtract 1234 1233 | rev
  1000

Wednesday, August 14, 2013

Associative Arrays in Bash

#!/bin/bash

# -A declares v to be an associative array
# [key]=vlaue
declare -A v
v=(
    ["var1"]="variable 01"
    ["var2"]="variable 02"
    ["var3"]="variable 03"
    ["var4"]="variable 01"
)

# ${!v[@]} gives us the keys
# to access the value use ${v[key]}
for k in ${!v[@]}
do
    echo "v: [$k] => [${v[$k]}]"
done


# key can have spaces
declare -A vws
vws=(
    ["var 1"]="variable 01"
    ["var 2"]="variable 02"
)

echo "vsw: [var 1] => [${vws['var 1']}]"
echo "vsw: [var 2] => [${vws['var 2']}]"

Output:
v: [var1] => [variable 01]
v: [var3] => [variable 03]
v: [var2] => [variable 02]
v: [var4] => [variable 01]
vsw: [var 1] => [variable 01]
vsw: [var 2] => [variable 02]
Reference: http://www.linuxjournal.com/content/bash-associative-arrays

Saturday, March 26, 2011

Command-line dictionary

It just parse the website wordnetweb and extract the meaning of the word/phrase given. You need lynx to run this script successfully.


References:
http://ubuntuforums.org/showthread.php?t=371482
http://wordnetweb.princeton.edu/perl/webwn

Wednesday, May 12, 2010

Script to mount partitions from image file in linux

#!/bin/bash

usage ()
{
    cat <<EOF
Usage: $(basename $0) <image file>
EOF
exit 1;
}

# Check for the input argument
if [ $# -ne 1 ]; then
    usage
fi

sfdisk -l -uS $1 

sfdisk -l -uS $1 2>/dev/null | awk '
           BEGIN {
             i = 1
           }
           /sectors\/track$/ {
             split ($2, array, ":"); 
             imagefile = array[1];
           }
           /^Units = sectors of/ {
             secsize = $5;
           }
           !/#sectors|sectors\/track$|^$|^Units = sectors of/ && $4 != 0 {
             partoffset = secsize * $2;
             cmd = sprintf ("test -e /mnt/tttt%d", i);
             cmd1 = sprintf ("test -d /mnt/tttt%d", i);
             if (system (cmd) != 0)
             {
               cmd = sprintf ("mkdir /mnt/tttt%d 2>/dev/null", i);
               if (system (cmd) != 0)
               {
                 printf ("Error: Could not create the director /mnt/tttt%d.Please try with root privilege.\n", i);
                 exit;
               }
             }
             else if (system (cmd) != 0)
             {
               printf ("Error: /mnt/tttt%d is not a directory.\n", i);
               exit;
             }
             cmd = sprintf ("mount -o loop,offset=%d %s /mnt/tttt%d", partoffset, imagefile, i); 
             if (system (cmd) != 0)
             {
               exit;
             }
             printf ("Mounting: %s ---> /mnt/tttt%d\n", $1, i);
             i++;
           }'

  To run this script:
  root@ubuntu:~# mountImageFile.sh <image file>

  Run this script with root privilege.

Note: This script will not work for large partitions because of the limitation in sfdisk.
Reference: http://lists.samba.org/archive/linux/2005-April/013444.html & manpages awk and sfdisk

Wednesday, March 10, 2010

Pocket Linux Guide


The Linux Documentation Project


This document takes baby steps to explains how to build a small diskette-based GNU/Linux system. This is a very good starting place for Linux newbies to understand how basic linux system works.

Get information about all the network interfaces in linux

This program lists all active network interfaces in the system with associated IP address, MAC address and the subnetmask.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#define __KERNEL__
#include <asm/types.h>
#undef __KERNEL__

#include <linux/ethtool.h>
#include <linux/sockios.h>

#include <net/if.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>

/* this is straight from beej's network tutorial. It is a nice wrapper
 * for inet_ntop and helpes to make the program IPv6 ready
 */
char *get_ip_str(const struct sockaddr *sa, char *s, size_t maxlen)
{
  switch(sa->sa_family) {
    case AF_INET:
      inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), s, maxlen);
      break;

    case AF_INET6:
      inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), s, maxlen);
      break;

    default:
      strncpy(s, "Unknown AF", maxlen);
      return NULL;
  }

  return s;
}

int main (int argc, char **argv)
{
  char          buf[1024] = {0};
  struct ifconf ifc = {0};
  struct ifreq *ifr = NULL;
  int           sck = 0;
  int           nInterfaces = 0;
  int           i = 0;
  struct ifreq ifr_subnet;
  struct sockaddr *addr_subnet = NULL;

  /* Get a socket handle. */
  sck = socket(AF_INET, SOCK_DGRAM, 0);
  if(-1 == sck) {
    perror("socket");
    return 1;
  }

  /* Query available interfaces. */
  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if(-1 == ioctl(sck, SIOCGIFCONF, &ifc)) {
    perror("ioctl(SIOCGIFCONF)");
    close (sck);
    return 1;
  }

  /* Iterate through the list of interfaces. */
  ifr = ifc.ifc_req;
  nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
  for(i = 0; i < nInterfaces; i++)
  {
    struct ifreq *item = &ifr[i];

    /* Show the device name and IP address */
    struct sockaddr *addr = &(item->ifr_addr);
    char ip[INET6_ADDRSTRLEN];
    printf("%s: IP %s",
           item->ifr_name,
           get_ip_str(addr, ip, INET6_ADDRSTRLEN));

    /* Get the MAC address */
    if(-1 == ioctl(sck, SIOCGIFHWADDR, item)) {
      perror("ioctl(SIOCGIFHWADDR)");
      close (sck);
      return 1;
    }

    /* display result */
    printf(", MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ",
           (unsigned char)item->ifr_hwaddr.sa_data[0],
           (unsigned char)item->ifr_hwaddr.sa_data[1],
           (unsigned char)item->ifr_hwaddr.sa_data[2],
           (unsigned char)item->ifr_hwaddr.sa_data[3],
           (unsigned char)item->ifr_hwaddr.sa_data[4],
           (unsigned char)item->ifr_hwaddr.sa_data[5]);

    /* Reset the memory allocated for ifreq */
    memset (&ifr_subnet, 0, sizeof (struct ifreq));

    /* Update interface name into ifreq */
    strcpy (ifr_subnet.ifr_name, item->ifr_name);

    /* Call ioctl function */
    if(-1 == ioctl (sck, SIOCGIFNETMASK, &ifr_subnet ))
    {
      perror("ioctl(SIOCGIFNETMASK)");
      close (sck);
      return 1;
    }
    addr_subnet = &(ifr_subnet.ifr_addr);
    printf("SubnetMask: %s\n", get_ip_str(addr_subnet, ip, INET6_ADDRSTRLEN));
  }

  close (sck);
  return 0;
}

Reference: http://www.adamrisi.com/?p=84

Tuesday, March 9, 2010

Simple PING implementation in C

#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/signal.h>
#include <string.h>

#define DEFDATALEN      56
#define MAXIPLEN        60
#define MAXICMPLEN      76

static char *hostname = NULL;

static int in_cksum(unsigned short *buf, int sz)
{
  int nleft = sz;
  int sum = 0;
  unsigned short *w = buf;
  unsigned short ans = 0;
  
  while (nleft > 1) {
    sum += *w++;
    nleft -= 2;
  }
  
  if (nleft == 1) {
    *(unsigned char *) (&ans) = *(unsigned char *) w;
    sum += ans;
  }
  
  sum = (sum >> 16) + (sum & 0xFFFF);
  sum += (sum >> 16);
  ans = ˜sum;
  return (ans);
}

static void noresp(int ign)
{
  printf("No response from %s\n", hostname);
  exit(0);
}

static void ping(const char *host)
{
  struct hostent *h;
  struct sockaddr_in pingaddr;
  struct icmp *pkt;
  int pingsock, c;
  char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
  
  if ((pingsock = socket(AF_INET, SOCK_RAW, 1)) < 0) {       /* 1 == ICMP */
    perror("ping: creating a raw socket");
    exit(1);
  }
  
  /* drop root privs if running setuid */
  setuid(getuid());
  
  memset(&pingaddr, 0, sizeof(struct sockaddr_in));
  
  pingaddr.sin_family = AF_INET;
  if (!(h = gethostbyname(host))) {
    fprintf(stderr, "ping: unknown host %s\n", host);
    exit(1);
  }
  memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr));
  hostname = h->h_name;
  
  pkt = (struct icmp *) packet;
  memset(pkt, 0, sizeof(packet));
  pkt->icmp_type = ICMP_ECHO;
  pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet));
  
  c = sendto(pingsock, packet, sizeof(packet), 0,
             (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in));
  
  if (c < 0 || c != sizeof(packet)) {
    if (c < 0)
      perror("ping: sendto");
    fprintf(stderr, "ping: write incomplete\n");
    exit(1);
  }
  
  signal(SIGALRM, noresp);
  alarm(2);                                     /* give the host 5000ms to respond */
  /* listen for replies */
  while (1) {
    struct sockaddr_in from;
    size_t fromlen = sizeof(from);
    
    if ((c = recvfrom(pingsock, packet, sizeof(packet), 0,
                      (struct sockaddr *) &from, &fromlen)) < 0) {
      if (errno == EINTR)
        continue;
      perror("ping: recvfrom");
      continue;
    }
    if (c >= 76) {                   /* ip + icmp */
      struct iphdr *iphdr = (struct iphdr *) packet;
      
      pkt = (struct icmp *) (packet + (iphdr->ihl << 2));      /* skip ip hdr */
      if (pkt->icmp_type == ICMP_ECHOREPLY)
        break;
    }
  }
  printf("%s is alive!\n", hostname);
  return;
}

int main ()
{
  ping ("192.168.1.2");

}

Reference: http://www.koders.com/c/fid30EA22902AFF5800481BBC6F65DADCDAF92D6E37.aspx