#include <unistd.h>

int strncmp(const char *p1, const char *p2, unsigned n)
{
  while ((n > 0) && (*p1 == *p2) && (*p1 != '\0'))
  {
    ++p1;
    ++p2;
    --n;
  }
  return (*p1 == *p2) ? 0 :
         ((*p1 < *p2 ) ? -1 : 1);
}

unsigned strlen(const char *p1)
{
  unsigned n;
  n = 0;
  while (*(p1++) != '\0') 
  {
    ++n;
  }
  return n;
}

void mymemcpy(void *dest, void *src, unsigned n)
{
  while (n > 0)
  {
    *((char*)dest++) = *((char*)src++);
    --n;
  }
}

struct Student
{
  char ssn[10];
  char firstname[20];
  char lastname[20];
};

int student_cmp(const struct Student *pStudent1, 
                const struct Student *pStudent2)
{
  return strncmp(pStudent1->ssn, pStudent2->ssn, sizeof(pStudent1->ssn));
}

int find_min_index(struct Student *array, unsigned i, unsigned n)
{
  unsigned m = i;
  unsigned j = i + 1;
  i = i + 1;
  while (j < n)
  {
    if (student_cmp(&array[j], &array[m]) < 0)
    {
      m = j;
    }
    ++j;
  }
  return m;
}

void sort(struct Student *array, unsigned n)
{
  unsigned i;
  struct Student t;
  unsigned m;

  i = 0;
  while (i < n-1)
  {
    m = find_min_index(array, i, n);
    mymemcpy(&t, &array[m], sizeof(*array));
    mymemcpy(&array[m], &array[i], sizeof(*array));
    mymemcpy(&array[i], &t, sizeof(*array));
    i = i + 1;
  }
}

int read_record(struct Student *dest)
{
  int n;
  n = read(0, dest->ssn, sizeof(dest->ssn));
  if (n != 0)
  {
    dest->ssn[n-1] = '\0';
    n = read(0, dest->firstname, sizeof(dest->firstname));
    if (n != 0)
    {
      dest->firstname[n-1] = '\0';
      n = read(0, dest->lastname, sizeof(dest->lastname));
      if (n != 0)
      {
        dest->lastname[n-1] = '\0';
      }
    }
  }
  return n;
}

void write_record(struct Student *src)
{
  char ch;
  ch = '\n';
  write(1, src->ssn, strlen(src->ssn));
  write(1, &ch, 1);
  ch = ' ';
  write(1, src->firstname, strlen(src->firstname));
  write(1, &ch, 1);
  write(1, src->lastname, strlen(src->lastname));
  ch = '\n';
  write(1, &ch, 1);
}

int main(void)
{
  const int MAXSTUDENT = 20;
  struct Student myclass[MAXSTUDENT];
  unsigned i;
  unsigned j;
  int result;
  
  i = 0;
  do
  {
    result = read_record(&myclass[i]);
    if (result != 0)
    {
      i = i + 1;
    }
  } while ((i < MAXSTUDENT) && (result != 0));
  sort(myclass, i);
  j = 0;
  while (j < i)
  {
    write_record(&myclass[j]);
    j = j + 1;
  }
}

