IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 18424


Ignore:
Timestamp:
Jul 3, 2008, 10:26:51 PM (18 years ago)
Author:
eugene
Message:

updates from HEAD

Location:
branches/eam_branch_20080421/Ohana
Files:
6 added
82 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branch_20080421/Ohana/configure

    r12842 r18424  
    22
    33# strip out CC, CFLAGS, CPPFLAGS, LDFLAGS and set env vars
    4 while (( $# > 0 )); do
     4while ( test $# -gt 0 ); do
     5
    56  skip=0
    67
    78  # strip out CC, set as env variable
    89  echo $1 | grep "^CC=" > /dev/null
    9   if (( $? == 0 )) ; then
     10  if ( test $? -eq 0 ) ; then
    1011    val=`echo $1 | sed "s|^CC=||"`
    1112    export CC=$val
     
    1415  # strip out CFLAGS, set as env variable
    1516  echo $1 | grep "^CFLAGS=" > /dev/null
    16   if (( $? == 0 )) ; then
     17  if ( test $? -eq 0 ) ; then
    1718    val=`echo $1 | sed "s|^CFLAGS=||"`
    1819    export CFLAGS=$val
     
    2122  # strip out CPPFLAGS, set as env variable
    2223  echo $1 | grep "^CPPFLAGS=" > /dev/null
    23   if (( $? == 0 )) ; then
     24  if ( test $? -eq 0 ) ; then
    2425    val=`echo $1 | sed "s|^CPPFLAGS=||"`
    2526    export CPPFLAGS=$val
     
    2829  # strip out LDFLAGS, set as env variable
    2930  echo $1 | grep "^LDFLAGS=" > /dev/null
    30   if (( $? == 0 )) ; then
     31  if ( test $? -eq 0 ) ; then
    3132    val=`echo $1 | sed "s|^LDFLAGS=||"`
    3233    export LDFLAGS=$val
    3334    skip=1
    3435  fi
    35   if (( $skip == 0 )) ; then
     36  if ( test $skip -eq 0 ) ; then
    3637    args="$args $1"
    3738  fi
  • branches/eam_branch_20080421/Ohana/configure.tcsh

    r16968 r18424  
    350350foreach f ( ncurses curses termcap )
    351351    foreach g ( $libpath $libdir $syslibpath )
     352        # echo "trying $g"
    352353        set name = $g/lib$f.a
     354        # echo "trying $name"
    353355        if (-e $name[1]) goto got_curses;
    354356        set name = $g/lib$f.$dlltype
     357        # echo "trying $name"
     358        if (-e $name[1]) goto got_curses;
     359    end
     360    # try versioned libraries such as .so.N
     361    foreach g ( $libpath $libdir $syslibpath )
     362        # echo "trying $g"
     363        set name = $g/lib$f.$dlltype.*
     364        # echo "$#name : $name[1]"
     365        if ($#name < 2) continue
     366        # echo "trying $name[1]"
    355367        if (-e $name[1]) goto got_curses;
    356368    end
     
    359371echo "missing a valid curses library"
    360372echo "missing: $faillibs"
    361 echo "please find one of them and install them in $lib"
     373echo "please find one of them and install them in $libpath"
    362374exit 1
    363375
  • branches/eam_branch_20080421/Ohana/src/addstar/include/addstar.h

    r16983 r18424  
    129129SkyRegion UserPatch;  // used by MODE CAT
    130130char     *SELECT_2MASS_QUALITY;  // used only by get2mass_as
     131int NREFSTAR_GROUP;
    131132
    132133/*** addstar prototypes ***/
  • branches/eam_branch_20080421/Ohana/src/addstar/src/args.c

    r16992 r18424  
    66  int i, N;
    77  int QUALITY_AIRMASS;
     8
     9  // a global used by find_matches_refstars.c (value is 1 except for load2mass)
     10  NREFSTAR_GROUP = 1;
    811
    912  /* check for help request */
  • branches/eam_branch_20080421/Ohana/src/addstar/src/args_client.c

    r16992 r18424  
    1111    help ();
    1212  }
     13
     14  // a global used by find_matches_refstars.c (value is 1 except for load2mass)
     15  NREFSTAR_GROUP = 1;
    1316
    1417  /*** check for command line options ***/
  • branches/eam_branch_20080421/Ohana/src/addstar/src/args_load2mass.c

    r16938 r18424  
    1111    help ();
    1212  }
     13
     14  // a global used by find_matches_refstars.c (value is 1 except for load2mass)
     15  NREFSTAR_GROUP = 3;
    1316
    1417  /*** check for command line options ***/
  • branches/eam_branch_20080421/Ohana/src/addstar/src/args_sedstar.c

    r7696 r18424  
    1111    help ();
    1212  }
     13
     14  // a global used by find_matches_refstars.c (value is 1 except for load2mass)
     15  NREFSTAR_GROUP = 1;
    1316
    1417  /*** check for command line options ***/
  • branches/eam_branch_20080421/Ohana/src/addstar/src/args_server.c

    r7691 r18424  
    1111    help ();
    1212  }
     13
     14  // a global used by find_matches_refstars.c (value is 1 except for load2mass)
     15  NREFSTAR_GROUP = 1;
    1316
    1417  /* restrict to a portion of the sky? (REFCAT only) */
  • branches/eam_branch_20080421/Ohana/src/addstar/src/find_matches_refstars.c

    r17469 r18424  
    1414  Coords tcoords;
    1515  int Nsecfilt;
     16
     17  if ((NREFSTAR_GROUP != 1) && (NREFSTAR_GROUP != 3)) {
     18      fprintf (stderr, "ERROR: NREFSTAR_GROUP NOT SET!\n");
     19      exit (1);
     20  }
    1621
    1722  /* photcode data -- should not have to modify secfilt / average */
     
    98103
    99104  /** find matched stars **/
     105  // XXX could use NREFSTAR_GROUP to do this match more quicky
    100106  for (i = j = 0; (i < Nstars) && (j < Nave); ) {
    101107   
     
    225231     the reference up-to-date with known stars only */
    226232
    227   for (i = 0; (i < Nstars) && !options.only_match; i++) {
     233  for (i = 0; (i < Nstars) && !options.only_match; i+=NREFSTAR_GROUP) {
    228234    N = N1[i];
    229235    if (stars[N][0].found >= 0) continue;
     
    232238    catalog[0].average[Nave].D             = stars[N][0].D;
    233239    catalog[0].average[Nave].Xp            = 0;
    234     catalog[0].average[Nave].Nmeasure      = 1;
     240    catalog[0].average[Nave].Nmeasure      = NREFSTAR_GROUP;
    235241    catalog[0].average[Nave].Nmissing      = 0;
    236242    catalog[0].average[Nave].measureOffset = Nmeas;
     
    268274    }
    269275
    270     catalog[0].measure[Nmeas].dR       = 0.0;
    271     catalog[0].measure[Nmeas].dD       = 0.0;
    272     catalog[0].measure[Nmeas].M        = stars[N][0].M;
    273     catalog[0].measure[Nmeas].dM       = stars[N][0].dM;
    274     catalog[0].measure[Nmeas].Mcal     = 0;
    275     catalog[0].measure[Nmeas].t        = (stars[N][0].t == 0) ? TIMEREF : stars[N][0].t; /** careful : time_t vs e_time **/
    276     catalog[0].measure[Nmeas].averef   = Nave;
    277     catalog[0].measure[Nmeas].photcode = stars[N][0].code;
    278     catalog[0].measure[Nmeas].dophot   = 0;
    279     catalog[0].measure[Nmeas].dbFlags  = 0;
    280     catalog[0].measure[Nmeas].dt       = 0xffff;
    281 
    282     catalog[0].measure[Nmeas].photFlags = stars[N][0].flags; // XXX make sure these are zero'ed as needed
    283     catalog[0].measure[Nmeas].qPSF      = 0;
    284     catalog[0].measure[Nmeas].psfChisq  = 0;
    285     catalog[0].measure[Nmeas].crNsigma  = 0;
    286     catalog[0].measure[Nmeas].extNsigma = 0;
    287     catalog[0].measure[Nmeas].Sky       = 0;
    288     catalog[0].measure[Nmeas].dSky      = 0;
    289 
    290     catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
    291 
    292     catalog[0].measure[Nmeas].detID     = 0;
    293     catalog[0].measure[Nmeas].imageID   = 0;
    294 
    295     catalog[0].measure[Nmeas].dXccd     = 0;
    296     catalog[0].measure[Nmeas].dYccd     = 0;
    297 
    298     catalog[0].measure[Nmeas].Xccd     = stars[N][0].X; // XXX make sure these are zero'ed as needed
    299     catalog[0].measure[Nmeas].Yccd     = stars[N][0].Y; // XXX make sure these are zero'ed as needed
    300 
    301     catalog[0].measure[Nmeas].airmass  = 0;
    302     catalog[0].measure[Nmeas].Map      = NAN;
    303     catalog[0].measure[Nmeas].FWx      = stars[N][0].fx; // XXX make sure these are zero'ed as needed
    304     catalog[0].measure[Nmeas].FWy      = stars[N][0].fy; // XXX make sure these are zero'ed as needed
    305     catalog[0].measure[Nmeas].theta    = stars[N][0].df; // XXX make sure these are zero'ed as needed
    306 
    307     catalog[0].measure[Nmeas].Xccd     = 0.0;
    308     catalog[0].measure[Nmeas].Yccd     = 0.0;
    309 
    310     stars[N][0].found = Nmeas;
    311     next[last] = Nmeas;
    312     next[Nmeas] = -1;
    313     last = Nmeas;
    314     Nmeas ++;
    315     if (Nmeas == NMEAS) {
    316       NMEAS = Nmeas + 1000;
    317       REALLOCATE (next, int, NMEAS);
    318       REALLOCATE (catalog[0].measure, Measure, NMEAS);
    319     }
     276    for (j = 0; j < NREFSTAR_GROUP; j++) {
     277      N = N1[i + j];
     278      catalog[0].measure[Nmeas].dR       = 0.0;
     279      catalog[0].measure[Nmeas].dD       = 0.0;
     280      catalog[0].measure[Nmeas].M        = stars[N][0].M;
     281      catalog[0].measure[Nmeas].dM       = stars[N][0].dM;
     282      catalog[0].measure[Nmeas].Mcal     = 0;
     283      catalog[0].measure[Nmeas].t        = (stars[N][0].t == 0) ? TIMEREF : stars[N][0].t; /** careful : time_t vs e_time **/
     284      catalog[0].measure[Nmeas].averef   = Nave;
     285      catalog[0].measure[Nmeas].photcode = stars[N][0].code;
     286      catalog[0].measure[Nmeas].dophot   = 0;
     287      catalog[0].measure[Nmeas].dbFlags  = 0;
     288      catalog[0].measure[Nmeas].dt       = 0xffff;
     289
     290      catalog[0].measure[Nmeas].photFlags = stars[N][0].flags; // XXX make sure these are zero'ed as needed
     291      catalog[0].measure[Nmeas].qPSF      = 0;
     292      catalog[0].measure[Nmeas].psfChisq  = 0;
     293      catalog[0].measure[Nmeas].crNsigma  = 0;
     294      catalog[0].measure[Nmeas].extNsigma = 0;
     295      catalog[0].measure[Nmeas].Sky       = 0;
     296      catalog[0].measure[Nmeas].dSky      = 0;
     297
     298      catalog[0].measure[Nmeas].stargal   = 0; // XXX not yet set
     299
     300      catalog[0].measure[Nmeas].detID     = 0;
     301      catalog[0].measure[Nmeas].imageID   = 0;
     302
     303      catalog[0].measure[Nmeas].dXccd     = 0;
     304      catalog[0].measure[Nmeas].dYccd     = 0;
     305
     306      catalog[0].measure[Nmeas].Xccd     = stars[N][0].X; // XXX make sure these are zero'ed as needed
     307      catalog[0].measure[Nmeas].Yccd     = stars[N][0].Y; // XXX make sure these are zero'ed as needed
     308
     309      catalog[0].measure[Nmeas].airmass  = 0;
     310      catalog[0].measure[Nmeas].Map      = NAN;
     311      catalog[0].measure[Nmeas].FWx      = stars[N][0].fx; // XXX make sure these are zero'ed as needed
     312      catalog[0].measure[Nmeas].FWy      = stars[N][0].fy; // XXX make sure these are zero'ed as needed
     313      catalog[0].measure[Nmeas].theta    = stars[N][0].df; // XXX make sure these are zero'ed as needed
     314
     315      catalog[0].measure[Nmeas].Xccd     = 0.0;
     316      catalog[0].measure[Nmeas].Yccd     = 0.0;
     317
     318      stars[N][0].found = Nmeas;
     319      next[last] = Nmeas;
     320      next[Nmeas] = -1;
     321      last = Nmeas;
     322      Nmeas ++;
     323      if (Nmeas == NMEAS) {
     324        NMEAS = Nmeas + 1000;
     325        REALLOCATE (next, int, NMEAS);
     326        REALLOCATE (catalog[0].measure, Measure, NMEAS);
     327      }
     328    }
     329
    320330    Nave ++;
    321331    if (Nave == NAVE) {
  • branches/eam_branch_20080421/Ohana/src/kapa2/include/structures.h

    r16810 r18424  
    138138  char isaxis, areticks, islabel, islog;
    139139  double fx, dfx, fy, dfy;  /* axis location on graphic */
     140  double lweight;
     141  int color;
    140142} Axis;
    141143
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/DrawFrame.c

    r17469 r18424  
    88 
    99  int i, fx, fy, dfx, dfy, P, IsLabel, IsMajor;
    10   double range, major, minor, first, next;
     10  double range, major, minor, first, next, lweight;
    1111
    1212  graphic = GetGraphic();
    13 
    14   // XXX why is this called for every redraw?
    15   DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->fore, graphic->back);
    1613
    1714  /* each axis is drawn independently, but ticks and labels are placed according to
     
    2320    dfy = graph[0].axis[i].dfy;
    2421    P = hypot ((double)graph[0].axis[(i+1)%2].dfx, (double)graph[0].axis[(i+1)%2].dfy);
     22
     23    lweight = MAX (0, MIN (10, graph[0].axis[i].lweight));
     24    XSetLineAttributes (graphic->display, graphic->gc, lweight, LineSolid, CapNotLast, JoinMiter);
     25    XSetForeground (graphic->display, graphic->gc, graphic->color[graph[0].axis[i].color]);
     26    DrawRotTextInit (graphic->display, graphic->window, graphic->gc, graphic->color[graph[0].axis[i].color], graphic->back);
    2527
    2628    if (graph[0].axis[i].isaxis) {
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/InterpretKeys.c

    r16256 r18424  
    152152
    153153    case XK_KP_Add:
    154       image[0].image[0].zero += 0.1*image[0].image[0].range;
     154      if (modstate & ControlMask) {
     155          image[0].image[0].zero -= 0.05*image[0].image[0].range;
     156          image[0].image[0].range *= 1.1;
     157      } else {
     158          image[0].image[0].zero += 0.1*image[0].image[0].range;
     159      }
     160      SetColorScale (graphic, image);
     161      Remap (graphic, image);
    155162      Reorient (graphic, image, image[0].picture.X, image[0].picture.Y, 0);
    156163      break;
    157164    case XK_KP_Subtract:
    158       image[0].image[0].zero -= 0.1*image[0].image[0].range;
     165      if (modstate & ControlMask) {
     166          image[0].image[0].zero += 0.05*image[0].image[0].range;
     167          image[0].image[0].range *= 0.90;
     168      } else {
     169          image[0].image[0].zero -= 0.1*image[0].image[0].range;
     170      }
     171      SetColorScale (graphic, image);
     172      Remap (graphic, image);
    159173      Reorient (graphic, image, image[0].picture.X, image[0].picture.Y, 0);
    160174      break;
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/LoadFrame.c

    r14590 r18424  
    33int LoadFrame (int sock) {
    44 
    5   int i;
     5  int i, color;
    66  char Axis[16], Labels[16], Ticks[16];
     7  double lweight;
    78  Section *section;
    89  KapaGraphWidget *graph;
     
    2425  graph[0].axis[2].max = graph[0].axis[0].max;
    2526 
     27  KiiScanMessage (sock, "%lf %d", &lweight, &color);
     28
    2629  KiiScanMessage (sock, "%s %s %s", Axis, Labels, Ticks);
    2730
    2831  for (i = 0; i < 4; i++) {
     32    graph[0].axis[i].lweight = lweight;
     33    graph[0].axis[i].color = color;
     34
    2935    switch (Axis[i]) {
    3036    case '0':
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/Remap16.c

    r16391 r18424  
    8686
    8787    /**** fill in area to the left of the picture ****/
    88     for (jj = 0; (i_start > 0) && (jj < expand_out); jj++) {
     88    for (jj = 0; (i_start > 0) && (jj < expand_out) && (j + jj < dy); jj++) {
    8989      out_pix2 = out_pix + jj*dx;
    9090      for (i = 0; i < i_start; i++, out_pix2++) {
     
    104104        pixvalue = pixel[*in_pix2];
    105105        out_pix2 = out_pix;
    106         for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
     106        for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++, out_pix2+=(dx-expand_out)) {
    107107          for (ii = 0; ii < expand_out; ii++, out_pix2++) {
    108108            *out_pix2 = pixvalue;
     
    114114   
    115115    /**** fill in area to the right of the picture ****/
    116     for (jj = 0; jj < expand_out; jj++) {
     116    for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++) {
    117117      out_pix2 = out_pix + jj*dx;
    118118      for (i = i_end; i < dx; i++, out_pix2++) {
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/Remap24.c

    r16256 r18424  
    8484
    8585    /**** fill in area to the left of the picture ****/
    86     for (jj = 0; (i_start > 0) && (jj < expand_out); jj++) {
     86    for (jj = 0; (i_start > 0) && (jj < expand_out) && (j + jj < dy); jj++) {
    8787      out_pix2 = out_pix + jj*(3*dx + extra);
    8888      for (i = 0; i < i_start; i++, out_pix2+=3) {
     
    108108        pixvalue3 = pixel3[*in_pix2];
    109109        out_pix2 = out_pix;
    110         for (jj = 0; jj < expand_out; jj++, out_pix2+=3*(dx-expand_out)+extra) {
     110        for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++, out_pix2+=3*(dx-expand_out)+extra) {
    111111          for (ii = 0; ii < expand_out; ii++, out_pix2+=3) {
    112112            out_pix2[0] = pixvalue1;
     
    120120   
    121121    /**** fill in area to the right of the picture ****/
    122     for (jj = 0; jj < expand_out; jj++) {
     122    for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++) {
     123      //    for (jj = 0; jj < expand_out; jj++) {
    123124      out_pix2 = out_pix + jj*(3*dx+extra);
    124125      for (i = i_end; i < dx; i++, out_pix2+=3) {
     
    142143
    143144  picture[0].pix = XCreateImage (graphic[0].display, graphic[0].visual, graphic[0].depth, ZPixmap, 0,
    144                                         picture[0].data, picture[0].dx, picture[0].dy, 32, 0);
     145                                 picture[0].data, picture[0].dx, picture[0].dy, 32, 0);
    145146
    146147  free (pixel1);
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/Remap32.c

    r17121 r18424  
    100100
    101101    /**** fill in area to the left of the picture ****/
    102     for (jj = 0; (i_start > 0) && (jj < expand_out); jj++) {
     102    for (jj = 0; (i_start > 0) && (jj < expand_out) && (j + jj < dy); jj++) {
    103103      out_pix2 = out_pix + jj*dx;
    104104      for (i = 0; i < i_start; i++, out_pix2++) {
     
    118118        pixvalue = pixel[*in_pix2];
    119119        out_pix2 = out_pix;
    120         for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
     120        for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++, out_pix2+=(dx-expand_out)) {
    121121          for (ii = 0; ii < expand_out; ii++, out_pix2++) {
    122122            *out_pix2 = pixvalue;
     
    133133
    134134    /**** fill in area to the right of the picture ****/
    135     for (jj = 0; jj < expand_out; jj++) {
     135    for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++) {
    136136      out_pix2 = out_pix + jj*dx;
    137137      for (i = i_end; i < dx; i++, out_pix2++) {
  • branches/eam_branch_20080421/Ohana/src/kapa2/src/Remap8.c

    r16256 r18424  
    6969
    7070    /**** fill in area to the left of the picture ****/
    71     for (jj = 0; (i_start > 0) && (jj < expand_out); jj++) {
     71    for (jj = 0; (i_start > 0) && (jj < expand_out) && (j + jj < dy); jj++) {
    7272      out_pix2 = out_pix + jj*dx;
    7373      for (i = 0; i < i_start; i++, out_pix2++) {
     
    8787        pixvalue = pixel[*in_pix2];
    8888        out_pix2 = out_pix;
    89         for (jj = 0; jj < expand_out; jj++, out_pix2+=(dx-expand_out)) {
     89        for (jj = 0; (jj < expand_out) & (j + jj < dy); jj++, out_pix2+=(dx-expand_out)) {
    9090          for (ii = 0; ii < expand_out; ii++, out_pix2++) {
    9191            *out_pix2 = pixvalue;
     
    9797   
    9898    /**** fill in area to the right of the picture ****/
    99     for (jj = 0; jj < expand_out; jj++) {
     99    for (jj = 0; (jj < expand_out) && (j + jj < dy); jj++) {
    100100      out_pix2 = out_pix + jj*dx;
    101101      for (i = i_end; i < dx; i++, out_pix2++) {
     
    115115  }
    116116  picture[0].pix = XCreateImage (graphic[0].display, graphic[0].visual, graphic[0].depth, ZPixmap, 0,
    117                                         picture[0].data, picture[0].dx, picture[0].dy, 8, 0);
     117                                 picture[0].data, picture[0].dx, picture[0].dy, 8, 0);
    118118  free (pixel);
    119119}
  • branches/eam_branch_20080421/Ohana/src/libfits/extern/ricecomp.c

    r15487 r18424  
     1
     2// 2008.06.22 EAM : This code was taken from CFITSIO and included in Ohana for rice
     3// decompression.  In order to include this .c file (or future upgrades), we include our own
     4// version of ricecomp.h (not the one available in the CFITSIO tree) and include it instead of
     5// fitsio2.h.  This file defines our own version of ffpmsg. 
     6
    17/*
    28  The following code was written by Richard White at STScI and made
     
    2329#include <stdlib.h>
    2430#include <string.h>
    25 #include "ricecomp.h"  /* originally included in rcomp.c file (WDP) */
     31
     32typedef unsigned char Buffer_t;
     33
     34typedef struct {
     35        int bitbuffer;          /* bit buffer                                   */
     36        int bits_to_go;         /* bits to go in buffer                 */
     37        Buffer_t *start;        /* start of buffer                              */
     38        Buffer_t *current;      /* current position in buffer   */
     39        Buffer_t *end;          /* end of buffer                                */
     40} Buffer;
     41
     42#define putcbuf(c,mf)   ((*(mf->current)++ = c), 0)
     43
    2644// #include "fitsio2.h"
    27 
     45# include "ricecomp.h"
    2846
    2947static void start_outputing_bits(Buffer *buffer);
     
    3250
    3351/* this routine used to be called 'rcomp'  (WDP)  */
     52/*---------------------------------------------------------------------------*/
    3453
    3554int fits_rcomp(int a[],         /* input array                  */
     
    5574     */
    5675    bsize = 4;
    57 /*    nblock = 32; */
     76
     77/*    nblock = 32; now an input parameter*/
    5878    /*
    5979     * From bsize derive:
     
    6282     * BBITS = bits/pixel for direct coding
    6383     */
     84
     85/*
    6486    switch (bsize) {
    6587    case 1:
     
    7698        break;
    7799    default:
    78         fprintf (stderr, "rdecomp: bsize must be 1, 2, or 4 bytes");
     100        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
    79101        return(-1);
    80102    }
     103*/
     104
     105    /* move out of switch block, to tweak performance */
     106    fsbits = 5;
     107    fsmax = 25;
    81108    bbits = 1<<fsbits;
    82109
     
    93120    diff = (unsigned int *) malloc(nblock*sizeof(unsigned int));
    94121    if (diff == (unsigned int *) NULL) {
    95         fprintf (stderr, "fits_rcomp: insufficient memory");
     122        ffpmsg("fits_rcomp: insufficient memory");
    96123        return(-1);
    97124    }
     
    103130    /* write out first int value to the first 4 bytes of the buffer */
    104131    if (output_nbits(buffer, a[0], 32) == EOF) {
    105         fprintf (stderr, "rice_encode: end of buffer");
     132        ffpmsg("rice_encode: end of buffer");
    106133        free(diff);
    107134        return(-1);
     
    133160            lastpix = nextpix;
    134161        }
     162
    135163        /*
    136164         * compute number of bits to split from sum
     
    140168        psum = ((unsigned int) dpsum ) >> 1;
    141169        for (fs = 0; psum>0; fs++) psum >>= 1;
     170
    142171        /*
    143172         * write the codes
     
    149178             */
    150179            if (output_nbits(buffer, fsmax+1, fsbits) == EOF) {
    151                 fprintf (stderr, "rice_encode: end of buffer");
     180                ffpmsg("rice_encode: end of buffer");
    152181                free(diff);
    153182                return(-1);
     
    155184            for (j=0; j<thisblock; j++) {
    156185                if (output_nbits(buffer, diff[j], bbits) == EOF) {
    157                     fprintf (stderr, "rice_encode: end of buffer");
     186                    ffpmsg("rice_encode: end of buffer");
    158187                    free(diff);
    159188                    return(-1);
     
    167196             */
    168197            if (output_nbits(buffer, 0, fsbits) == EOF) {
    169                 fprintf (stderr, "rice_encode: end of buffer");
     198                ffpmsg("rice_encode: end of buffer");
    170199                free(diff);
    171200                return(-1);
     
    174203            /* normal case: not either very high or very low entropy */
    175204            if (output_nbits(buffer, fs+1, fsbits) == EOF) {
    176                 fprintf (stderr, "rice_encode: end of buffer");
     205                ffpmsg("rice_encode: end of buffer");
    177206                free(diff);
    178207                return(-1);
     
    196225                } else {
    197226                    lbitbuffer <<= lbits_to_go;
    198                     if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) {
    199                         fprintf (stderr, "rice_encode: end of buffer");
    200                         free(diff);
    201                         return(-1);
    202                     }
     227                    putcbuf(lbitbuffer & 0xff,buffer);
     228
    203229                    for (top -= lbits_to_go; top>=8; top -= 8) {
    204                         if (putcbuf(0, buffer) == EOF) {
    205                             fprintf (stderr, "rice_encode: end of buffer");
    206                             free(diff);
    207                             return(-1);
    208                         }
     230                        putcbuf(0, buffer);
    209231                    }
    210232                    lbitbuffer = 1;
     
    222244                    lbits_to_go -= fs;
    223245                    while (lbits_to_go <= 0) {
    224                         if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer)==EOF) {
    225                             fprintf (stderr, "rice_encode: end of buffer");
    226                             free(diff);
    227                             return(-1);
    228                         }
     246                        putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer);
    229247                        lbits_to_go += 8;
    230248                    }
    231249                }
     250            }
     251
     252            /* check if overflowed output buffer */
     253            if (buffer->current > buffer->end) {
     254                 ffpmsg("rice_encode: end of buffer");
     255                 free(diff);
     256                 return(-1);
     257            }
     258            buffer->bitbuffer = lbitbuffer;
     259            buffer->bits_to_go = lbits_to_go;
     260        }
     261    }
     262    done_outputing_bits(buffer);
     263    free(diff);
     264    /*
     265     * return number of bytes used
     266     */
     267    return(buffer->current - buffer->start);
     268}
     269/*---------------------------------------------------------------------------*/
     270
     271int fits_rcomp_short(
     272          short a[],            /* input array                  */
     273          int nx,               /* number of input pixels       */
     274          unsigned char *c,     /* output buffer                */
     275          int clen,             /* max length of output         */
     276          int nblock)           /* coding block size            */
     277{
     278Buffer bufmem, *buffer = &bufmem;
     279int bsize, i, j, thisblock;
     280
     281/*
     282NOTE: in principle, the following 2 variable could be declared as 'short'
     283but in fact the code runs faster (on 32-bit Linux at least) as 'int'
     284*/
     285int lastpix, nextpix;
     286/* int pdiff; */
     287short pdiff;
     288int v, fs, fsmask, top, fsmax, fsbits, bbits;
     289int lbitbuffer, lbits_to_go;
     290/* unsigned int psum; */
     291unsigned short psum;
     292double pixelsum, dpsum;
     293unsigned int *diff;
     294
     295    /*
     296     * Original size of each pixel (bsize, bytes) and coding block
     297     * size (nblock, pixels)
     298     * Could make bsize a parameter to allow more efficient
     299     * compression of short & byte images.
     300     */
     301    bsize = 2;
     302
     303/*    nblock = 32; now an input parameter */
     304    /*
     305     * From bsize derive:
     306     * FSBITS = # bits required to store FS
     307     * FSMAX = maximum value for FS
     308     * BBITS = bits/pixel for direct coding
     309     */
     310
     311/*
     312    switch (bsize) {
     313    case 1:
     314        fsbits = 3;
     315        fsmax = 6;
     316        break;
     317    case 2:
     318        fsbits = 4;
     319        fsmax = 14;
     320        break;
     321    case 4:
     322        fsbits = 5;
     323        fsmax = 25;
     324        break;
     325    default:
     326        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
     327        return(-1);
     328    }
     329*/
     330
     331    /* move these out of switch block to further tweak performance */
     332    fsbits = 4;
     333    fsmax = 14;
     334    bbits = 1<<fsbits;
     335
     336    /*
     337     * Set up buffer pointers
     338     */
     339    buffer->start = c;
     340    buffer->current = c;
     341    buffer->end = c+clen;
     342    buffer->bits_to_go = 8;
     343    /*
     344     * array for differences mapped to non-negative values
     345     */
     346    diff = (unsigned int *) malloc(nblock*sizeof(unsigned int));
     347    if (diff == (unsigned int *) NULL) {
     348        ffpmsg("fits_rcomp: insufficient memory");
     349        return(-1);
     350    }
     351    /*
     352     * Code in blocks of nblock pixels
     353     */
     354    start_outputing_bits(buffer);
     355
     356    /* write out first short value to the first 2 bytes of the buffer */
     357    if (output_nbits(buffer, a[0], 16) == EOF) {
     358        ffpmsg("rice_encode: end of buffer");
     359        free(diff);
     360        return(-1);
     361    }
     362
     363    lastpix = a[0];  /* the first difference will always be zero */
     364
     365    thisblock = nblock;
     366    for (i=0; i<nx; i += nblock) {
     367        /* last block may be shorter */
     368        if (nx-i < nblock) thisblock = nx-i;
     369        /*
     370         * Compute differences of adjacent pixels and map them to unsigned values.
     371         * Note that this may overflow the integer variables -- that's
     372         * OK, because we can recover when decompressing.  If we were
     373         * compressing shorts or bytes, would want to do this arithmetic
     374         * with short/byte working variables (though diff will still be
     375         * passed as an int.)
     376         *
     377         * compute sum of mapped pixel values at same time
     378         * use double precision for sum to allow 32-bit integer inputs
     379         */
     380        pixelsum = 0.0;
     381        for (j=0; j<thisblock; j++) {
     382            nextpix = a[i+j];
     383            pdiff = nextpix - lastpix;
     384            diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1));
     385            pixelsum += diff[j];
     386            lastpix = nextpix;
     387        }
     388        /*
     389         * compute number of bits to split from sum
     390         */
     391        dpsum = (pixelsum - (thisblock/2) - 1)/thisblock;
     392        if (dpsum < 0) dpsum = 0.0;
     393/*      psum = ((unsigned int) dpsum ) >> 1; */
     394        psum = ((unsigned short) dpsum ) >> 1;
     395        for (fs = 0; psum>0; fs++) psum >>= 1;
     396
     397        /*
     398         * write the codes
     399         * fsbits ID bits used to indicate split level
     400         */
     401        if (fs >= fsmax) {
     402            /* Special high entropy case when FS >= fsmax
     403             * Just write pixel difference values directly, no Rice coding at all.
     404             */
     405            if (output_nbits(buffer, fsmax+1, fsbits) == EOF) {
     406                ffpmsg("rice_encode: end of buffer");
     407                free(diff);
     408                return(-1);
     409            }
     410            for (j=0; j<thisblock; j++) {
     411                if (output_nbits(buffer, diff[j], bbits) == EOF) {
     412                    ffpmsg("rice_encode: end of buffer");
     413                    free(diff);
     414                    return(-1);
     415                }
     416            }
     417        } else if (fs == 0 && pixelsum == 0) {
     418            /*
     419             * special low entropy case when FS = 0 and pixelsum=0 (all
     420             * pixels in block are zero.)
     421             * Output a 0 and return
     422             */
     423            if (output_nbits(buffer, 0, fsbits) == EOF) {
     424                ffpmsg("rice_encode: end of buffer");
     425                free(diff);
     426                return(-1);
     427            }
     428        } else {
     429            /* normal case: not either very high or very low entropy */
     430            if (output_nbits(buffer, fs+1, fsbits) == EOF) {
     431                ffpmsg("rice_encode: end of buffer");
     432                free(diff);
     433                return(-1);
     434            }
     435            fsmask = (1<<fs) - 1;
     436            /*
     437             * local copies of bit buffer to improve optimization
     438             */
     439            lbitbuffer = buffer->bitbuffer;
     440            lbits_to_go = buffer->bits_to_go;
     441            for (j=0; j<thisblock; j++) {
     442                v = diff[j];
     443                top = v >> fs;
     444                /*
     445                 * top is coded by top zeros + 1
     446                 */
     447                if (lbits_to_go >= top+1) {
     448                    lbitbuffer <<= top+1;
     449                    lbitbuffer |= 1;
     450                    lbits_to_go -= top+1;
     451                } else {
     452                    lbitbuffer <<= lbits_to_go;
     453                    putcbuf(lbitbuffer & 0xff,buffer);
     454                    for (top -= lbits_to_go; top>=8; top -= 8) {
     455                        putcbuf(0, buffer);
     456                    }
     457                    lbitbuffer = 1;
     458                    lbits_to_go = 7-top;
     459                }
     460                /*
     461                 * bottom FS bits are written without coding
     462                 * code is output_nbits, moved into this routine to reduce overheads
     463                 * This code potentially breaks if FS>24, so I am limiting
     464                 * FS to 24 by choice of FSMAX above.
     465                 */
     466                if (fs > 0) {
     467                    lbitbuffer <<= fs;
     468                    lbitbuffer |= v & fsmask;
     469                    lbits_to_go -= fs;
     470                    while (lbits_to_go <= 0) {
     471                        putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer);
     472                        lbits_to_go += 8;
     473                    }
     474                }
     475            }
     476            /* check if overflowed output buffer */
     477            if (buffer->current > buffer->end) {
     478                 ffpmsg("rice_encode: end of buffer");
     479                 free(diff);
     480                 return(-1);
     481            }
     482            buffer->bitbuffer = lbitbuffer;
     483            buffer->bits_to_go = lbits_to_go;
     484        }
     485    }
     486    done_outputing_bits(buffer);
     487    free(diff);
     488    /*
     489     * return number of bytes used
     490     */
     491    return(buffer->current - buffer->start);
     492}
     493/*---------------------------------------------------------------------------*/
     494
     495int fits_rcomp_byte(
     496          signed char a[],              /* input array                  */
     497          int nx,               /* number of input pixels       */
     498          unsigned char *c,     /* output buffer                */
     499          int clen,             /* max length of output         */
     500          int nblock)           /* coding block size            */
     501{
     502Buffer bufmem, *buffer = &bufmem;
     503int bsize, i, j, thisblock;
     504
     505/*
     506NOTE: in principle, the following 2 variable could be declared as 'short'
     507but in fact the code runs faster (on 32-bit Linux at least) as 'int'
     508*/
     509int lastpix, nextpix;
     510/* int pdiff; */
     511signed char pdiff;
     512int v, fs, fsmask, top, fsmax, fsbits, bbits;
     513int lbitbuffer, lbits_to_go;
     514/* unsigned int psum; */
     515unsigned char psum;
     516double pixelsum, dpsum;
     517unsigned int *diff;
     518
     519    /*
     520     * Original size of each pixel (bsize, bytes) and coding block
     521     * size (nblock, pixels)
     522     * Could make bsize a parameter to allow more efficient
     523     * compression of short & byte images.
     524     */
     525    bsize = 1;
     526
     527/*    nblock = 32; now an input parameter */
     528    /*
     529     * From bsize derive:
     530     * FSBITS = # bits required to store FS
     531     * FSMAX = maximum value for FS
     532     * BBITS = bits/pixel for direct coding
     533     */
     534
     535/*
     536    switch (bsize) {
     537    case 1:
     538        fsbits = 3;
     539        fsmax = 6;
     540        break;
     541    case 2:
     542        fsbits = 4;
     543        fsmax = 14;
     544        break;
     545    case 4:
     546        fsbits = 5;
     547        fsmax = 25;
     548        break;
     549    default:
     550        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
     551        return(-1);
     552    }
     553*/
     554
     555    /* move these out of switch block to further tweak performance */
     556    fsbits = 3;
     557    fsmax = 6;
     558    bbits = 1<<fsbits;
     559
     560    /*
     561     * Set up buffer pointers
     562     */
     563    buffer->start = c;
     564    buffer->current = c;
     565    buffer->end = c+clen;
     566    buffer->bits_to_go = 8;
     567    /*
     568     * array for differences mapped to non-negative values
     569     */
     570    diff = (unsigned int *) malloc(nblock*sizeof(unsigned int));
     571    if (diff == (unsigned int *) NULL) {
     572        ffpmsg("fits_rcomp: insufficient memory");
     573        return(-1);
     574    }
     575    /*
     576     * Code in blocks of nblock pixels
     577     */
     578    start_outputing_bits(buffer);
     579
     580    /* write out first byte value to the first  byte of the buffer */
     581    if (output_nbits(buffer, a[0], 8) == EOF) {
     582        ffpmsg("rice_encode: end of buffer");
     583        free(diff);
     584        return(-1);
     585    }
     586
     587    lastpix = a[0];  /* the first difference will always be zero */
     588
     589    thisblock = nblock;
     590    for (i=0; i<nx; i += nblock) {
     591        /* last block may be shorter */
     592        if (nx-i < nblock) thisblock = nx-i;
     593        /*
     594         * Compute differences of adjacent pixels and map them to unsigned values.
     595         * Note that this may overflow the integer variables -- that's
     596         * OK, because we can recover when decompressing.  If we were
     597         * compressing shorts or bytes, would want to do this arithmetic
     598         * with short/byte working variables (though diff will still be
     599         * passed as an int.)
     600         *
     601         * compute sum of mapped pixel values at same time
     602         * use double precision for sum to allow 32-bit integer inputs
     603         */
     604        pixelsum = 0.0;
     605        for (j=0; j<thisblock; j++) {
     606            nextpix = a[i+j];
     607            pdiff = nextpix - lastpix;
     608            diff[j] = (unsigned int) ((pdiff<0) ? ~(pdiff<<1) : (pdiff<<1));
     609            pixelsum += diff[j];
     610            lastpix = nextpix;
     611        }
     612        /*
     613         * compute number of bits to split from sum
     614         */
     615        dpsum = (pixelsum - (thisblock/2) - 1)/thisblock;
     616        if (dpsum < 0) dpsum = 0.0;
     617/*      psum = ((unsigned int) dpsum ) >> 1; */
     618        psum = ((unsigned char) dpsum ) >> 1;
     619        for (fs = 0; psum>0; fs++) psum >>= 1;
     620
     621        /*
     622         * write the codes
     623         * fsbits ID bits used to indicate split level
     624         */
     625        if (fs >= fsmax) {
     626            /* Special high entropy case when FS >= fsmax
     627             * Just write pixel difference values directly, no Rice coding at all.
     628             */
     629            if (output_nbits(buffer, fsmax+1, fsbits) == EOF) {
     630                ffpmsg("rice_encode: end of buffer");
     631                free(diff);
     632                return(-1);
     633            }
     634            for (j=0; j<thisblock; j++) {
     635                if (output_nbits(buffer, diff[j], bbits) == EOF) {
     636                    ffpmsg("rice_encode: end of buffer");
     637                    free(diff);
     638                    return(-1);
     639                }
     640            }
     641        } else if (fs == 0 && pixelsum == 0) {
     642            /*
     643             * special low entropy case when FS = 0 and pixelsum=0 (all
     644             * pixels in block are zero.)
     645             * Output a 0 and return
     646             */
     647            if (output_nbits(buffer, 0, fsbits) == EOF) {
     648                ffpmsg("rice_encode: end of buffer");
     649                free(diff);
     650                return(-1);
     651            }
     652        } else {
     653            /* normal case: not either very high or very low entropy */
     654            if (output_nbits(buffer, fs+1, fsbits) == EOF) {
     655                ffpmsg("rice_encode: end of buffer");
     656                free(diff);
     657                return(-1);
     658            }
     659            fsmask = (1<<fs) - 1;
     660            /*
     661             * local copies of bit buffer to improve optimization
     662             */
     663            lbitbuffer = buffer->bitbuffer;
     664            lbits_to_go = buffer->bits_to_go;
     665            for (j=0; j<thisblock; j++) {
     666                v = diff[j];
     667                top = v >> fs;
     668                /*
     669                 * top is coded by top zeros + 1
     670                 */
     671                if (lbits_to_go >= top+1) {
     672                    lbitbuffer <<= top+1;
     673                    lbitbuffer |= 1;
     674                    lbits_to_go -= top+1;
     675                } else {
     676                    lbitbuffer <<= lbits_to_go;
     677                    putcbuf(lbitbuffer & 0xff,buffer);
     678                    for (top -= lbits_to_go; top>=8; top -= 8) {
     679                        putcbuf(0, buffer);
     680                    }
     681                    lbitbuffer = 1;
     682                    lbits_to_go = 7-top;
     683                }
     684                /*
     685                 * bottom FS bits are written without coding
     686                 * code is output_nbits, moved into this routine to reduce overheads
     687                 * This code potentially breaks if FS>24, so I am limiting
     688                 * FS to 24 by choice of FSMAX above.
     689                 */
     690                if (fs > 0) {
     691                    lbitbuffer <<= fs;
     692                    lbitbuffer |= v & fsmask;
     693                    lbits_to_go -= fs;
     694                    while (lbits_to_go <= 0) {
     695                        putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer);
     696                        lbits_to_go += 8;
     697                    }
     698                }
     699            }
     700            /* check if overflowed output buffer */
     701            if (buffer->current > buffer->end) {
     702                 ffpmsg("rice_encode: end of buffer");
     703                 free(diff);
     704                 return(-1);
    232705            }
    233706            buffer->bitbuffer = lbitbuffer;
     
    270743int lbitbuffer;
    271744int lbits_to_go;
     745    /* AND mask for the right-most n bits */
     746    static unsigned int mask[33] =
     747         {0,
     748          0x1,       0x3,       0x7,       0xf,       0x1f,       0x3f,       0x7f,       0xff,
     749          0x1ff,     0x3ff,     0x7ff,     0xfff,     0x1fff,     0x3fff,     0x7fff,     0xffff,
     750          0x1ffff,   0x3ffff,   0x7ffff,   0xfffff,   0x1fffff,   0x3fffff,   0x7fffff,   0xffffff,
     751          0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};
    272752
    273753    /*
     
    282762         */
    283763        lbitbuffer <<= lbits_to_go;
    284         lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<<lbits_to_go)-1);
    285         if (putcbuf(lbitbuffer & 0xff,buffer) == EOF) return(EOF);
     764/*      lbitbuffer |= (bits>>(n-lbits_to_go)) & ((1<<lbits_to_go)-1); */
     765        lbitbuffer |= (bits>>(n-lbits_to_go)) & *(mask+lbits_to_go);
     766        putcbuf(lbitbuffer & 0xff,buffer);
    286767        n -= lbits_to_go;
    287768        lbits_to_go = 8;
    288769    }
    289770    lbitbuffer <<= n;
    290     lbitbuffer |= ( bits & ((1<<n)-1) );
     771/*    lbitbuffer |= ( bits & ((1<<n)-1) ); */
     772    lbitbuffer |= ( bits & *(mask+n) );
    291773    lbits_to_go -= n;
    292774    while (lbits_to_go <= 0) {
     
    294776         * bitbuffer full, put out top 8 bits
    295777         */
    296         if (putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer) == EOF)
    297             return(EOF);
     778        putcbuf((lbitbuffer>>(-lbits_to_go)) & 0xff,buffer);
    298779        lbits_to_go += 8;
    299780    }
     
    302783    return(0);
    303784}
    304 
    305785/*---------------------------------------------------------------------------*/
    306786/* Flush out the last bits */
     
    309789{
    310790    if(buffer->bits_to_go < 8) {
    311         if (putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer) == EOF)
     791        putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer);
     792       
     793/*      if (putcbuf(buffer->bitbuffer<<buffer->bits_to_go,buffer) == EOF)
    312794            return(EOF);
     795*/
    313796    }
    314797    return(0);
     
    334817*/
    335818
     819/*---------------------------------------------------------------------------*/
    336820/* this routine used to be called 'rdecomp'  (WDP)  */
    337821
     
    356840     */
    357841    bsize = 4;
    358 /*    nblock = 32; */
     842
     843/*    nblock = 32; now an input parameter */
    359844    /*
    360845     * From bsize derive:
     
    363848     * BBITS = bits/pixel for direct coding
    364849     */
     850
     851/*
    365852    switch (bsize) {
    366853    case 1:
     
    377864        break;
    378865    default:
    379         fprintf (stderr, "rdecomp: bsize must be 1, 2, or 4 bytes");
     866        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
    380867        return 1;
    381868    }
     869*/
     870
     871    /* move out of switch block, to tweak performance */
     872    fsbits = 5;
     873    fsmax = 25;
     874
    382875    bbits = 1<<fsbits;
    383876
    384     // XXX EAM : sensible code would put this in an init function,
    385     // with a provided cleanup function.  this is just generating
    386     // the number of 1 bits for any 8bit value
    387877    if (nonzero_count == (int *) NULL) {
    388878        /*
     
    394884        nonzero_count = (int *) malloc(256*sizeof(int));
    395885        if (nonzero_count == (int *) NULL) {
    396             fprintf (stderr, "rdecomp: insufficient memory");
     886            ffpmsg("rdecomp: insufficient memory");
    397887            return 1;
    398888        }
     
    411901    /* first 4 bytes of input buffer contain the value of the first */
    412902    /* 4 byte integer value, without any encoding */
    413    
    414     // XXX EAM : wow! this is just doing { lastpix = *(int *)c; } without a cast (encoded value is big-endian)
    415903   
    416904    lastpix = 0;
     
    437925        }
    438926        fs = (b >> nbits) - 1;
     927
    439928        b &= (1<<nbits)-1;
    440929        /* loop over the next block */
     
    494983                diff = (nzero<<fs) | (b>>nbits);
    495984                b &= (1<<nbits)-1;
     985
    496986                /* undo mapping and differencing */
    497987                if ((diff & 1) == 0) {
     
    505995        }
    506996        if (c > cend) {
    507             fprintf (stderr, "decompression error: hit end of compressed byte stream");
     997            ffpmsg("decompression error: hit end of compressed byte stream");
    508998            return 1;
    509999        }
    5101000    }
    5111001    if (c < cend) {
    512         fprintf (stderr, "decompression warning: unused bytes at end of compressed buffer");
     1002        ffpmsg("decompression warning: unused bytes at end of compressed buffer");
    5131003    }
    5141004    return 0;
    5151005}
     1006/*---------------------------------------------------------------------------*/
     1007/* this routine used to be called 'rdecomp'  (WDP)  */
     1008
     1009int fits_rdecomp_short (unsigned char *c,               /* input buffer                 */
     1010             int clen,                  /* length of input              */
     1011             unsigned short array[],    /* output array                 */
     1012             int nx,                    /* number of output pixels      */
     1013             int nblock)                /* coding block size            */
     1014{
     1015int i, imax;
     1016int bsize, k;
     1017int nbits, nzero, fs;
     1018unsigned char *cend, bytevalue;
     1019unsigned int b, diff, lastpix;
     1020int fsmax, fsbits, bbits;
     1021static int *nonzero_count = (int *)NULL;
     1022
     1023   /*
     1024     * Original size of each pixel (bsize, bytes) and coding block
     1025     * size (nblock, pixels)
     1026     * Could make bsize a parameter to allow more efficient
     1027     * compression of short & byte images.
     1028     */
     1029
     1030    bsize = 2;
     1031   
     1032/*    nblock = 32; now an input parameter */
     1033    /*
     1034     * From bsize derive:
     1035     * FSBITS = # bits required to store FS
     1036     * FSMAX = maximum value for FS
     1037     * BBITS = bits/pixel for direct coding
     1038     */
     1039
     1040/*
     1041    switch (bsize) {
     1042    case 1:
     1043        fsbits = 3;
     1044        fsmax = 6;
     1045        break;
     1046    case 2:
     1047        fsbits = 4;
     1048        fsmax = 14;
     1049        break;
     1050    case 4:
     1051        fsbits = 5;
     1052        fsmax = 25;
     1053        break;
     1054    default:
     1055        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
     1056        return 1;
     1057    }
     1058*/
     1059
     1060    /* move out of switch block, to tweak performance */
     1061    fsbits = 4;
     1062    fsmax = 14;
     1063
     1064    bbits = 1<<fsbits;
     1065
     1066    if (nonzero_count == (int *) NULL) {
     1067        /*
     1068         * nonzero_count is lookup table giving number of bits
     1069         * in 8-bit values not including leading zeros
     1070         */
     1071
     1072        /*  NOTE!!!  This memory never gets freed  */
     1073        nonzero_count = (int *) malloc(256*sizeof(int));
     1074        if (nonzero_count == (int *) NULL) {
     1075            ffpmsg("rdecomp: insufficient memory");
     1076            return 1;
     1077        }
     1078        nzero = 8;
     1079        k = 128;
     1080        for (i=255; i>=0; ) {
     1081            for ( ; i>=k; i--) nonzero_count[i] = nzero;
     1082            k = k/2;
     1083            nzero--;
     1084        }
     1085    }
     1086    /*
     1087     * Decode in blocks of nblock pixels
     1088     */
     1089
     1090    /* first 2 bytes of input buffer contain the value of the first */
     1091    /* 2 byte integer value, without any encoding */
     1092   
     1093    lastpix = 0;
     1094    bytevalue = c[0];
     1095    lastpix = lastpix | (bytevalue<<8);
     1096    bytevalue = c[1];
     1097    lastpix = lastpix | bytevalue;
     1098
     1099    c += 2; 
     1100    cend = c + clen - 2;
     1101
     1102    b = *c++;               /* bit buffer                       */
     1103    nbits = 8;              /* number of bits remaining in b    */
     1104    for (i = 0; i<nx; ) {
     1105        /* get the FS value from first fsbits */
     1106        nbits -= fsbits;
     1107        while (nbits < 0) {
     1108            b = (b<<8) | (*c++);
     1109            nbits += 8;
     1110        }
     1111        fs = (b >> nbits) - 1;
     1112
     1113        b &= (1<<nbits)-1;
     1114        /* loop over the next block */
     1115        imax = i + nblock;
     1116        if (imax > nx) imax = nx;
     1117        if (fs<0) {
     1118            /* low-entropy case, all zero differences */
     1119            for ( ; i<imax; i++) array[i] = lastpix;
     1120        } else if (fs==fsmax) {
     1121            /* high-entropy case, directly coded pixel values */
     1122            for ( ; i<imax; i++) {
     1123                k = bbits - nbits;
     1124                diff = b<<k;
     1125                for (k -= 8; k >= 0; k -= 8) {
     1126                    b = *c++;
     1127                    diff |= b<<k;
     1128                }
     1129                if (nbits>0) {
     1130                    b = *c++;
     1131                    diff |= b>>(-k);
     1132                    b &= (1<<nbits)-1;
     1133                } else {
     1134                    b = 0;
     1135                }
     1136   
     1137                /*
     1138                 * undo mapping and differencing
     1139                 * Note that some of these operations will overflow the
     1140                 * unsigned int arithmetic -- that's OK, it all works
     1141                 * out to give the right answers in the output file.
     1142                 */
     1143                if ((diff & 1) == 0) {
     1144                    diff = diff>>1;
     1145                } else {
     1146                    diff = ~(diff>>1);
     1147                }
     1148                array[i] = diff+lastpix;
     1149                lastpix = array[i];
     1150            }
     1151        } else {
     1152            /* normal case, Rice coding */
     1153            for ( ; i<imax; i++) {
     1154                /* count number of leading zeros */
     1155                while (b == 0) {
     1156                    nbits += 8;
     1157                    b = *c++;
     1158                }
     1159                nzero = nbits - nonzero_count[b];
     1160                nbits -= nzero+1;
     1161                /* flip the leading one-bit */
     1162                b ^= 1<<nbits;
     1163                /* get the FS trailing bits */
     1164                nbits -= fs;
     1165                while (nbits < 0) {
     1166                    b = (b<<8) | (*c++);
     1167                    nbits += 8;
     1168                }
     1169                diff = (nzero<<fs) | (b>>nbits);
     1170                b &= (1<<nbits)-1;
     1171
     1172                /* undo mapping and differencing */
     1173                if ((diff & 1) == 0) {
     1174                    diff = diff>>1;
     1175                } else {
     1176                    diff = ~(diff>>1);
     1177                }
     1178                array[i] = diff+lastpix;
     1179                lastpix = array[i];
     1180            }
     1181        }
     1182        if (c > cend) {
     1183            ffpmsg("decompression error: hit end of compressed byte stream");
     1184            return 1;
     1185        }
     1186    }
     1187    if (c < cend) {
     1188        ffpmsg("decompression warning: unused bytes at end of compressed buffer");
     1189    }
     1190    return 0;
     1191}
     1192/*---------------------------------------------------------------------------*/
     1193/* this routine used to be called 'rdecomp'  (WDP)  */
     1194
     1195int fits_rdecomp_byte (unsigned char *c,                /* input buffer                 */
     1196             int clen,                  /* length of input              */
     1197             unsigned char array[],     /* output array                 */
     1198             int nx,                    /* number of output pixels      */
     1199             int nblock)                /* coding block size            */
     1200{
     1201int i, imax;
     1202int bsize, k;
     1203int nbits, nzero, fs;
     1204unsigned char *cend;
     1205unsigned int b, diff, lastpix;
     1206int fsmax, fsbits, bbits;
     1207static int *nonzero_count = (int *)NULL;
     1208
     1209   /*
     1210     * Original size of each pixel (bsize, bytes) and coding block
     1211     * size (nblock, pixels)
     1212     * Could make bsize a parameter to allow more efficient
     1213     * compression of short & byte images.
     1214     */
     1215
     1216    bsize = 1;
     1217   
     1218/*    nblock = 32; now an input parameter */
     1219    /*
     1220     * From bsize derive:
     1221     * FSBITS = # bits required to store FS
     1222     * FSMAX = maximum value for FS
     1223     * BBITS = bits/pixel for direct coding
     1224     */
     1225
     1226/*
     1227    switch (bsize) {
     1228    case 1:
     1229        fsbits = 3;
     1230        fsmax = 6;
     1231        break;
     1232    case 2:
     1233        fsbits = 4;
     1234        fsmax = 14;
     1235        break;
     1236    case 4:
     1237        fsbits = 5;
     1238        fsmax = 25;
     1239        break;
     1240    default:
     1241        ffpmsg("rdecomp: bsize must be 1, 2, or 4 bytes");
     1242        return 1;
     1243    }
     1244*/
     1245
     1246    /* move out of switch block, to tweak performance */
     1247    fsbits = 3;
     1248    fsmax = 6;
     1249
     1250    bbits = 1<<fsbits;
     1251
     1252    if (nonzero_count == (int *) NULL) {
     1253        /*
     1254         * nonzero_count is lookup table giving number of bits
     1255         * in 8-bit values not including leading zeros
     1256         */
     1257
     1258        /*  NOTE!!!  This memory never gets freed  */
     1259        nonzero_count = (int *) malloc(256*sizeof(int));
     1260        if (nonzero_count == (int *) NULL) {
     1261            ffpmsg("rdecomp: insufficient memory");
     1262            return 1;
     1263        }
     1264        nzero = 8;
     1265        k = 128;
     1266        for (i=255; i>=0; ) {
     1267            for ( ; i>=k; i--) nonzero_count[i] = nzero;
     1268            k = k/2;
     1269            nzero--;
     1270        }
     1271    }
     1272    /*
     1273     * Decode in blocks of nblock pixels
     1274     */
     1275
     1276    /* first byte of input buffer contain the value of the first */
     1277    /* byte integer value, without any encoding */
     1278   
     1279    lastpix = c[0];
     1280    c += 1; 
     1281    cend = c + clen - 1;
     1282
     1283    b = *c++;               /* bit buffer                       */
     1284    nbits = 8;              /* number of bits remaining in b    */
     1285    for (i = 0; i<nx; ) {
     1286        /* get the FS value from first fsbits */
     1287        nbits -= fsbits;
     1288        while (nbits < 0) {
     1289            b = (b<<8) | (*c++);
     1290            nbits += 8;
     1291        }
     1292        fs = (b >> nbits) - 1;
     1293
     1294        b &= (1<<nbits)-1;
     1295        /* loop over the next block */
     1296        imax = i + nblock;
     1297        if (imax > nx) imax = nx;
     1298        if (fs<0) {
     1299            /* low-entropy case, all zero differences */
     1300            for ( ; i<imax; i++) array[i] = lastpix;
     1301        } else if (fs==fsmax) {
     1302            /* high-entropy case, directly coded pixel values */
     1303            for ( ; i<imax; i++) {
     1304                k = bbits - nbits;
     1305                diff = b<<k;
     1306                for (k -= 8; k >= 0; k -= 8) {
     1307                    b = *c++;
     1308                    diff |= b<<k;
     1309                }
     1310                if (nbits>0) {
     1311                    b = *c++;
     1312                    diff |= b>>(-k);
     1313                    b &= (1<<nbits)-1;
     1314                } else {
     1315                    b = 0;
     1316                }
     1317   
     1318                /*
     1319                 * undo mapping and differencing
     1320                 * Note that some of these operations will overflow the
     1321                 * unsigned int arithmetic -- that's OK, it all works
     1322                 * out to give the right answers in the output file.
     1323                 */
     1324                if ((diff & 1) == 0) {
     1325                    diff = diff>>1;
     1326                } else {
     1327                    diff = ~(diff>>1);
     1328                }
     1329                array[i] = diff+lastpix;
     1330                lastpix = array[i];
     1331            }
     1332        } else {
     1333            /* normal case, Rice coding */
     1334            for ( ; i<imax; i++) {
     1335                /* count number of leading zeros */
     1336                while (b == 0) {
     1337                    nbits += 8;
     1338                    b = *c++;
     1339                }
     1340                nzero = nbits - nonzero_count[b];
     1341                nbits -= nzero+1;
     1342                /* flip the leading one-bit */
     1343                b ^= 1<<nbits;
     1344                /* get the FS trailing bits */
     1345                nbits -= fs;
     1346                while (nbits < 0) {
     1347                    b = (b<<8) | (*c++);
     1348                    nbits += 8;
     1349                }
     1350                diff = (nzero<<fs) | (b>>nbits);
     1351                b &= (1<<nbits)-1;
     1352
     1353                /* undo mapping and differencing */
     1354                if ((diff & 1) == 0) {
     1355                    diff = diff>>1;
     1356                } else {
     1357                    diff = ~(diff>>1);
     1358                }
     1359                array[i] = diff+lastpix;
     1360                lastpix = array[i];
     1361            }
     1362        }
     1363        if (c > cend) {
     1364            ffpmsg("decompression error: hit end of compressed byte stream");
     1365            return 1;
     1366        }
     1367    }
     1368    if (c < cend) {
     1369        ffpmsg("decompression warning: unused bytes at end of compressed buffer");
     1370    }
     1371    return 0;
     1372}
  • branches/eam_branch_20080421/Ohana/src/libfits/extern/ricecomp.h

    r15487 r18424  
    1 /* @(#) buffer.h 1.1 98/07/21 12:34:27 */
    2 /* buffer.h: structure for compression to buffer rather than to a file, including
    3  *   bit I/O buffer
    4  *
    5  * R. White, 19 June 1998
    6  */
    71
    82
    9 typedef unsigned char Buffer_t;
     3// 2008.06.22 EAM : This code was taken from CFITSIO and included in Ohana for rice
     4// decompression.  In order to include this .c file (or future upgrades), we include our own
     5// version of ricecomp.h (not the one available in the CFITSIO tree) and include it instead of
     6// fitsio2.h.  This file defines our own version of ffpmsg.
    107
    11 typedef struct {
    12         int bitbuffer;          /* bit buffer                                   */
    13         int bits_to_go;         /* bits to go in buffer                 */
    14         Buffer_t *start;        /* start of buffer                              */
    15         Buffer_t *current;      /* current position in buffer   */
    16         Buffer_t *end;          /* end of buffer                                */
    17 } Buffer;
    18 
    19 #define buffree(mf)             (free(mf->start), free(mf))
    20 #define bufused(mf)             (mf->current - mf->start)
    21 #define bufreset(mf)    (mf->current = mf->start)
    22 
    23 /*
    24  * getcbuf, putcbuf macros for character IO to buffer
    25  * putcbuf returns EOF on end of buffer, else returns 0
    26  */
    27 #define getcbuf(mf) ((mf->current >= mf->end) ? EOF : *(mf->current)++)
    28 #define putcbuf(c,mf) \
    29         ((mf->current >= mf->end) ? \
    30         EOF :\
    31         ((*(mf->current)++ = c), 0))
    32 
    33 /*
    34  * bufalloc sets up buffer of length n
    35  */
    36 
    37 /*  not needed by CFITSIO
    38 
    39 static Buffer *bufalloc(int n)
    40 {
    41 Buffer *mf;
    42 
    43         mf = (Buffer *) malloc(sizeof(Buffer));
    44         if (mf == (Buffer *)NULL) return((Buffer *)NULL);
    45 
    46         mf->start = (Buffer_t *) malloc(n*sizeof(Buffer_t));
    47         if (mf->start == (Buffer_t *)NULL) {
    48                 free(mf);
    49                 return((Buffer *)NULL);
    50         }
    51         mf->bits_to_go = 8;
    52         mf->end = mf->start + n;
    53         mf->current = mf->start;
    54         return(mf);
    55 }
    56 */
    57 
    58 /*
    59  * bufrealloc extends buffer (or truncates it) by
    60  * reallocating memory
    61  */
    62 
    63 /* not needed by CFITSIO
    64 static int bufrealloc(Buffer *mf, int n)
    65 {
    66 int len;
    67 
    68         len = mf->current - mf->start;
    69 
    70         * silently throw away data if buffer is already longer than n *
    71         if (len>n) len = n;
    72         if (len<0) len = 0;
    73 
    74         mf->start = (Buffer_t *) realloc(mf->start, n*sizeof(Buffer_t));
    75         if (mf->start == (Buffer_t *)NULL) return(0);
    76 
    77         mf->end = mf->start + n;
    78         mf->current = mf->start + len;
    79         return(n);
    80 }
    81 */
    82 
    83 /*
    84  * bufdump dumps contents of buffer to outfile and resets
    85  * it to be empty.  Returns number of bytes written.
    86  *
    87  * Note we don't write out the bit buffer -- you must call
    88  * done_outputing_bits() first to ensure that the bit buffer
    89  * is written out.  I do it this way to allow incremental
    90  * buffer dumps while bit IO is still going on.
    91  */
    92 
    93 /*  not needed by CFITSIO
    94 
    95 static int bufdump(FILE *outfile, Buffer *buffer)
    96 {
    97 int ndump;
    98 
    99         ndump = bufused(buffer);
    100         if (fwrite(buffer->start, 1, ndump, outfile) != ndump) {
    101                 fprintf(stderr, "bufdump: error in write\n");
    102                 exit(1);
    103     }
    104         bufreset(buffer);
    105         return(ndump);
    106 }
    107 */
     8#define ffpmsg(MSG) fprintf(stderr, "%s\n", MSG)
  • branches/eam_branch_20080421/Ohana/src/libfits/header/F_copy_H.c

    r15487 r18424  
    2323  out[0].bscale = in[0].bscale;
    2424
     25  if (out[0].buffer != NULL) free (out[0].buffer);
    2526  ALLOCATE (out[0].buffer, char, out[0].size);
    2627 
  • branches/eam_branch_20080421/Ohana/src/libfits/include/gfitsio.h

    r16995 r18424  
    161161int     gfits_extension_is_compressed  PROTO((Header *header));
    162162int     gfits_tile_size                PROTO((Matrix *matrix, int *otile, int *ztile));
    163 int     gfits_uncompressed_data_pixsize PROTO((char *cmptype, int out_bitpix));
     163int     gfits_uncompressed_data_pixsize PROTO((char *cmptype, int out_bitpix, char **optname, char **optvalue, int Noptions));
    164164int     gfits_vartable_heap_pixsize    PROTO((char format));
    165165
  • branches/eam_branch_20080421/Ohana/src/libfits/matrix/F_compress_M.c

    r16970 r18424  
    1818  return (FALSE); }
    1919
    20 # define MOD_KEYWORD(NAME,ZNAME,TYPE,IN,OUT) { \
    21   gfits_scan (header, ZNAME, TYPE, 1, IN); \
    22   gfits_delete (header, ZNAME, 1); \
    23   gfits_print (header, NAME, TYPE, 1, OUT); }
     20# define MOD_KEYWORD(ZNAME,NAME,TYPE,IN,OUT) { \
     21    if (gfits_scan (header, ZNAME, TYPE, 1, IN)) { \
     22      gfits_modify (header, NAME, TYPE, 1, OUT); \
     23    } \
     24    gfits_delete (header, ZNAME, 1); }
    2425
    2526# define MOD_KEYWORD_REQUIRED(ZNAME,NAME,TYPE,IN,OUT) { \
    2627  if (!gfits_scan (header, ZNAME, TYPE, 1, IN)) ESCAPE; \
    2728  gfits_delete (header, ZNAME, 1); \
    28   gfits_print (header, NAME, TYPE, 1, OUT); }
     29  gfits_modify (header, NAME, TYPE, 1, OUT); }
    2930
    3031int gfits_uncompress_image (Header *header, Matrix *matrix, FTable *ftable) {
     
    5556  // copy original header to output header
    5657  gfits_copy_header (ftable->header, header);
     58
     59  // delete ZIMAGE from output header
     60  gfits_delete (header, "ZIMAGE", 1);
    5761
    5862  // extract compression-specific keywords, update header as needed.
     
    7983    }
    8084  } else {
     85    gfits_delete (header, "ZTILE1", 1);
    8186    for (i = 1; i < header->Naxes; i++) {
    8287      snprintf (key, 10, "ZTILE%d", i + 1);
     
    143148    gfits_delete (header, "ZTENSION", 1);
    144149    gfits_modify_extended (header, exttype, "Image extension");
    145     // XXX validate that exttype == 'IMAGE'?
    146 
    147     MOD_KEYWORD ("ZPCOUNT",  "PCOUNT",   "%d", &header->pcount, header->pcount);
    148     MOD_KEYWORD ("ZGCOUNT",  "GCOUNT",   "%d", &header->gcount, header->gcount);
    149   }
    150 
    151   MOD_KEYWORD ("ZHECKSUM", "ZHECKSUM", "%s", checksum,        checksum);
     150
     151    // we may have an uncompressed PCOUNT / GCOUNT value, otherwise set to 0,1
     152    if (gfits_scan (header, "ZPCOUNT", "%d", 1, &header->pcount)) {
     153        gfits_delete (header, "ZPCOUNT", 1);
     154        gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
     155    } else {
     156        header->pcount = 0;
     157        gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
     158    }
     159    if (gfits_scan (header, "ZGCOUNT", "%d", 1, &header->gcount)) {
     160        gfits_delete (header, "ZGCOUNT", 1);
     161        gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
     162    } else {
     163        header->pcount = 1;
     164        gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
     165    }
     166  } else {
     167    header->pcount = 0;
     168    header->gcount = 1;
     169    gfits_modify (header, "PCOUNT", "%d", 1, header->pcount);
     170    gfits_modify (header, "GCOUNT", "%d", 1, header->gcount);
     171  }
     172
     173  MOD_KEYWORD ("ZHECKSUM", "CHECKSUM", "%s", checksum,        checksum);
    152174  MOD_KEYWORD ("ZDATASUM", "DATASUM",  "%s", datasum,         datasum);
    153175
     
    167189
    168190  if (!gfits_varlength_column_define (ftable, &zdef, zcol)) ESCAPE;
     191  gfits_delete (header, "TFIELDS", 1);
     192  snprintf (key, 10, "TTYPE%d", zcol);
     193  gfits_delete (header, key, 1);
     194  snprintf (key, 10, "TFORM%d", zcol);
     195  gfits_delete (header, key, 1);
    169196
    170197  // create the output image
     
    200227
    201228  // size of a pixel in the output from the decompression routine
    202   odata_pixsize = gfits_uncompressed_data_pixsize (cmptype, header[0].bitpix);
     229  odata_pixsize = gfits_uncompressed_data_pixsize (cmptype, header[0].bitpix, optname, optvalue, Noptions);
    203230  ALLOCATE (out, char, odata_pixsize*max_tile_size);
    204231
     
    385412
    386413    case 2:
    387       for (i = 0; i < Nzdata; i+=2) {
     414      for (i = 0; i < 2*Nzdata; i+=2) {
    388415        tmp = zdata[i];
    389416        zdata[i] = zdata[i+1];
     
    393420
    394421    case 4:
    395       for (i = 0; i < Nzdata; i+=4) {
     422      for (i = 0; i < 4*Nzdata; i+=4) {
    396423        tmp = zdata[i+1];
    397424        zdata[i+1] = zdata[i+2];
     
    404431
    405432    case 8:
    406       for (i = 0; i < Nzdata; i+=8) {
     433      for (i = 0; i < 8*Nzdata; i+=8) {
    407434        tmp = zdata[i+0];
    408435        zdata[i+0] = zdata[i+7];
     
    426453int gfits_extension_is_compressed (Header *header) {
    427454
    428     int has_extname, has_zimage, zimage;
    429     char extname[80];
    430 
     455    int has_extension, has_extname, has_zimage, zimage;
     456    char extname[80], extension[80];
     457
     458    has_extension = gfits_scan (header, "XTENSION", "%s", 1, extension);
    431459    has_extname = gfits_scan (header, "EXTNAME", "%s", 1, extname);
    432460    has_zimage  = gfits_scan (header, "ZIMAGE", "%t", 1, &zimage);
    433461
     462    if (has_extension && !strcmp (extension, "IMAGE")) return (FALSE);
    434463    if (has_zimage && zimage) return (TRUE);
    435464    if (has_extname) {
     
    453482}
    454483
    455 int gfits_uncompressed_data_pixsize (char *cmptype, int out_bitpix) {
     484int gfits_uncompressed_data_pixsize (char *cmptype, int out_bitpix, char **optname, char **optvalue, int Noptions) {
     485
     486  int i, Nbyte;
    456487
    457488  if (!strcasecmp(cmptype, "GZIP_1")) {
     
    459490  }
    460491  if (!strcasecmp(cmptype, "RICE_1")) {
     492
     493    // if BYTEPIX option is specified, use that for Nbyte
     494    for (i = 0; i < Noptions; i++) {
     495      if (!strcmp(optname[i], "BYTEPIX")) {
     496        Nbyte = atoi (optvalue[i]);
     497        return (Nbyte);
     498      }
     499    }
     500
    461501    return (4);
    462502  }
    463503  if (!strcasecmp(cmptype, "PLIO_1")) {
    464     return (1);
     504    return (4);
    465505  }
    466506  if (!strcasecmp(cmptype, "HCOMPRESS_1")) {
  • branches/eam_branch_20080421/Ohana/src/libfits/matrix/F_copy_M.c

    r7054 r18424  
    1616    matrix2[0].Naxis[i] = matrix1[0].Naxis[i];
    1717
     18  if (matrix2[0].buffer != NULL) free (matrix2[0].buffer);
    1819  ALLOCATE (matrix2[0].buffer, char, matrix2[0].size);
    1920 
  • branches/eam_branch_20080421/Ohana/src/libfits/matrix/F_create_M.c

    r15487 r18424  
    2727}
    2828
     29// XXX free buffer if non-null: need to double check for existing frees
  • branches/eam_branch_20080421/Ohana/src/libfits/matrix/F_uncompress_data.c

    r15657 r18424  
    66int fits_rcomp(int a[], int nx, unsigned char *c, int clen, int nblock);
    77int fits_rdecomp (unsigned char *c, int clen, unsigned int array[], int nx, int nblock);
     8int fits_rdecomp_short (unsigned char *c, int clen, unsigned short array[], int nx, int nblock);
     9int fits_rdecomp_byte (unsigned char *c, int clen, unsigned char array[], int nx, int nblock);
    810
    911/* functions defined in fits_hcompress.c */
     
    6062    // fprintf (stderr, "%d comp bytes; %d uncomp 'pixels', totals: %d %d\n", Nzdata, Npix, Ninsum, Noutsum);
    6163
    62     // rice decompression from the CFITSIO source tree : we need to tell it the expected number of pixels
    63     // is also REQUIRES 4byte output, which is fairly stupid.
    64     if (fits_rdecomp ((unsigned char *) zdata, Nzdata, (unsigned int *) outdata, Npix, blocksize)) {
    65       fprintf (stderr, "error in rice decompression\n");
    66       return (FALSE);
     64    switch (out_pixsize) {
     65      case 4:
     66        // rice decompression from the CFITSIO source tree : we need to tell it the expected number of pixels
     67        // is also REQUIRES 4byte output, which is fairly stupid.
     68        if (fits_rdecomp ((unsigned char *) zdata, Nzdata, (unsigned int *) outdata, Npix, blocksize)) {
     69          fprintf (stderr, "error in rice decompression\n");
     70          return (FALSE);
     71        }
     72        return (TRUE);
     73
     74      case 2:
     75        if (fits_rdecomp_short ((unsigned char *) zdata, Nzdata, (unsigned short *) outdata, Npix, blocksize)) {
     76          fprintf (stderr, "error in rice decompression\n");
     77          return (FALSE);
     78        }
     79        return (TRUE);
     80
     81      case 1:
     82        if (fits_rdecomp_byte ((unsigned char *) zdata, Nzdata, (unsigned char *) outdata, Npix, blocksize)) {
     83          fprintf (stderr, "error in rice decompression\n");
     84          return (FALSE);
     85        }
     86        return (TRUE);
     87       
     88      default:
     89        fprintf (stderr, "invalid output pixel size %d\n", out_pixsize);
     90        return (FALSE);
    6791    }
    68     return (TRUE);
     92   
    6993  }
    7094 
  • branches/eam_branch_20080421/Ohana/src/libfits/table/F_table_varlength.c

    r15487 r18424  
    7070void *gfits_varlength_column_pointer (FTable *ftable, VarLengthColumn *column, int row, int *length) {
    7171
     72  void *result;
    7273  int offset, Nx, *ptr;
    7374
     
    9293  offset = ptr[1];
    9394
    94   switch (column->format) {
    95     case 'X':
    96     case 'L':
    97     case 'A':
    98     case 'B': {
    99       char *result;
    100       result = (char *) ftable->buffer + column->heap_start + offset;
    101       return result;
    102     }
    103     case 'I': {
    104       short *result;
    105       result = (short *) ftable->buffer + column->heap_start + offset;
    106       return result;
    107     }
    108     case 'J': {
    109       int *result;
    110       result = (int *) ftable->buffer + column->heap_start + offset;
    111       return result;
    112     }
    113     case 'E':
    114     case 'C': {
    115       float *result;
    116       result = (float *) ftable->buffer + column->heap_start + offset;
    117       return result;
    118     }
    119     case 'D':
    120     case 'M': {
    121       double *result;
    122       result = (double *) ftable->buffer + column->heap_start + offset;
    123       return result;
    124     }
    125     case 'P':
    126     default:
    127       abort();
    128   }
    129   abort();
     95  result = (void *) (ftable->buffer + column->heap_start + offset);
     96  return result;
    13097}
    131 
  • branches/eam_branch_20080421/Ohana/src/libkapa/src/IOfuncs.c

    r16466 r18424  
    11# include <kapa_internal.h>
     2# define DEBUG 0
    23
    34/** these function expect to operate with a BLOCKing socket **/
     
    6364  status = read (device, buffer, 16);
    6465  buffer[16] = 0;
    65   if (status != 16) fprintf (stderr, "dropped message length\n");
     66  if (status != 16) {
     67      fprintf (stderr, "dropped message length\n");
     68  }
     69  if (DEBUG) fprintf (stderr, "recv buffer: %s\n", buffer);
    6670
    6771  /* find the message length, allocate space */
     
    7175  /* read Nbytes from the device */
    7276  status = read (device, message, Nbytes);
    73   if (status != Nbytes) fprintf (stderr, "Kii/Kapa comm error\n");
     77  if (status != Nbytes) {
     78      fprintf (stderr, "Kii/Kapa comm error\n");
     79  }
    7480  message[status] = 0;
    7581  /* make the string easy to parse */
    7682
    77   // fprintf (stderr, "recv: %s\n", message);
     83  if (DEBUG) fprintf (stderr, "recv: %s\n", message);
    7884
    7985  /* scan the incoming message */
     
    112118  write (device, string, length);
    113119
    114   // fprintf (stderr, "send: %s\n", string);
     120  if (DEBUG) fprintf (stderr, "send: %s\n", string);
    115121
    116122  free (string);
     
    129135  /* read Nbytes from the device */
    130136  status = read (device, message, length);
     137  if (DEBUG) fprintf (stderr, "recv message: %s\n", message);
    131138
    132139  if (status != length) {
  • branches/eam_branch_20080421/Ohana/src/libkapa/src/KapaWindow.c

    r14401 r18424  
    2323  KiiSendMessage (fd, "%12.6g %12.6g %12.6g %12.6g",
    2424                    graphdata[0].xmin, graphdata[0].xmax, graphdata[0].ymin, graphdata[0].ymax);
     25
     26  KiiSendMessage (fd, "%lf %d", graphdata[0].lweight, graphdata[0].color);
    2527
    2628  KiiSendMessage (fd, "%s %s %s", graphdata[0].axis, graphdata[0].labels, graphdata[0].ticks);
  • branches/eam_branch_20080421/Ohana/src/libohana/src/IOBufferOps.c

    r16060 r18424  
    5757    switch (errno) {
    5858    case EAGAIN:
    59     case EIO:
    60       /** no data available in pipe **/
     59    case EINTR:
     60      /** data not available in pipe or read interrupted : just try again **/
    6161      return (-1);
    6262    default:
    63       /** error reading from pipe **/
     63      /** serious error (buffer overflow, invalid fd, etc **/
    6464      perror ("ReadtoIOBuffer read error");
    6565      return (-2);
  • branches/eam_branch_20080421/Ohana/src/libohana/src/findexec.c

    r16212 r18424  
    213213
    214214  ALLOCATE (file, char, strlen(name) + 1);
    215   strcpy (file, name);
    216   c = strrchr (file, '/');
     215
     216  c = strrchr (name, '/');
    217217  if (c == (char *) NULL) {
    218218    strcpy (file, name);
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.astro/coord_systems.c

    r17469 r18424  
    5959          abort();
    6060      }
     61      break;
    6162    case COORD_GALACTIC:
    6263      switch (output) {
     
    7778          abort();
    7879      }
     80      break;
    7981    default:
    8082      abort();
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.astro/coords.c

    r12524 r18424  
    104104  gprint (GP_ERR, "USAGE: coords [buffer] (-c R D) | (-p X Y)\n");
    105105  gprint (GP_ERR, "only one of -p or -c can be used\n");
     106  gprint (GP_ERR, " -p : from pixels to ra/dec\n");
     107  gprint (GP_ERR, " -c : from ra/dec to pixels\n");
    106108 escape:
    107109  if (MOSAIC != NULL) free (MOSAIC);
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.basic/Makefile

    r16211 r18424  
    2222$(SRC)/config.$(ARCH).o     \
    2323$(SRC)/continue.$(ARCH).o   \
     24$(SRC)/basename.$(ARCH).o     \
    2425$(SRC)/dirname.$(ARCH).o     \
    2526$(SRC)/date.$(ARCH).o        \
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.basic/init.c

    r16426 r18424  
    11# include "basic.h"
    22
     3int basename_opihi  PROTO((int, char **));
    34int config          PROTO((int, char **));
    45int exec_sleep      PROTO((int, char **));
     
    4748  {1, "cd",            cd,                 "change directory"},
    4849  {1, "date",          date,               "get current date"},
     50  {1, "basename",      basename_opihi,     "built-in basename function"},
    4951  {1, "dirname",       dirname_opihi,      "built-in dirname function"},
    5052  {1, "echo",          echo,               "type this line *"},
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/Makefile

    r17123 r18424  
    8989$(SRC)/queuepop.$(ARCH).o       \
    9090$(SRC)/queueprint.$(ARCH).o     \
     91$(SRC)/queuesubstr.$(ARCH).o    \
    9192$(SRC)/queueinit.$(ARCH).o      \
    9293$(SRC)/radial.$(ARCH).o \
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/box.c

    r13479 r18424  
    1515  if (!GetGraph (&graphmode, &kapa, name)) return (FALSE);
    1616  FREE (name);
     17
     18  graphmode.lweight = 1;
     19  if ((N = get_argument (argc, argv, "-lw"))) {
     20    remove_argument (N, &argc, argv);
     21    graphmode.lweight = atof(argv[N]);
     22    remove_argument (N, &argc, argv);
     23  }
     24
     25  graphmode.color = KapaColorByName ("black");
     26  if ((N = get_argument (argc, argv, "-c"))) {
     27    remove_argument (N, &argc, argv);
     28    graphmode.color = KapaColorByName (argv[N]);
     29    if (graphmode.color == -1) return (FALSE);
     30    remove_argument (N, &argc, argv);
     31  }
    1732
    1833  strcpy (graphmode.ticks, "2222");
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/dbselect.c

    r13615 r18424  
    55int dbselect (int argc, char **argv) {
    66 
     7  time_t seconds;
    78  int i, j, Nbytes, Ncols, Nrows;
    89  char *query;
     
    8081    }
    8182    for (i = 0; i < Ncols; i++) {
    82       vec[i][0].elements[j] = atof (row[i]);
     83      if (row[i]) {
     84        switch (fields[i].type) {
     85          case FIELD_TYPE_TINY:
     86          case FIELD_TYPE_SHORT:
     87          case FIELD_TYPE_LONG:
     88          case FIELD_TYPE_INT24:
     89          case FIELD_TYPE_LONGLONG:
     90          case FIELD_TYPE_DECIMAL:
     91          case FIELD_TYPE_FLOAT:
     92          case FIELD_TYPE_DOUBLE:
     93            vec[i][0].elements[j] = atof (row[i]);
     94            break;
     95          case FIELD_TYPE_TIME:
     96          case FIELD_TYPE_DATE:
     97          case FIELD_TYPE_DATETIME:
     98            seconds = ohana_date_to_sec (row[i]);
     99            vec[i][0].elements[j] = ohana_sec_to_mjd (seconds);
     100            break;
     101          default:
     102            vec[i][0].elements[j] = NAN;
     103        }
     104      } else {
     105        vec[i][0].elements[j] = NAN;
     106      }
    83107    }
    84108  }
    85 
    86109  free (query);
    87110  free (vec);
     
    89112  return (TRUE);
    90113}
    91 
    92114# else
    93115
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/histogram.c

    r15514 r18424  
    3434  REALLOCATE (yvec[0].elements, float, yvec[0].Nelements);
    3535  bzero (yvec[0].elements, sizeof(float)*yvec[0].Nelements);
     36  if (Nbins < 1) {
     37      return (TRUE);
     38  }
    3639
    3740  V = xvec[0].elements;
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/init.c

    r17123 r18424  
    7474int queueprint       PROTO((int, char **));
    7575int queuepush        PROTO((int, char **));
     76int queuesubstr      PROTO((int, char **));
    7677int queuesize        PROTO((int, char **));
    7778int rd               PROTO((int, char **));
     
    196197  {1, "queuelist",    queuelist,        "list defined queues"},
    197198  {1, "queueload",    queueload,        "load queue from command"},
     199  {1, "queuesubstr",  queuesubstr,      "bulk replace strings in queue"},
    198200  {1, "queuesize",    queuesize,        "show queue size"},
    199201  {1, "rd",           rd,               "load fits image"},
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/rd.c

    r15661 r18424  
    182182    Header theader;
    183183    ftable.header = &theader;
     184    ftable.header[0].buffer = NULL;
    184185    gfits_copy_header (&buf[0].header, ftable.header);
    185186    status = gfits_fread_ftable_data (f, &ftable);  // this just reads the bytes (not even a SWAP)
    186187    status = gfits_uncompress_image (&buf[0].header, &buf[0].matrix, &ftable);
     188    // uncompressing the image leaves the format as an extension
     189    gfits_extended_to_primary (&buf[0].header, TRUE, "Standard FITS");
    187190    gfits_free_table (&ftable);
    188191    // XXX this currently does not work for a cube (we get a cube back, not a specific plane)
     
    190193    sprintf (region, "-1 -1 -1 -1 %d %d", (plane - 1), plane);
    191194    status = gfits_fread_matrix_segment (f, &buf[0].matrix, &buf[0].header, region);
    192     fclose (f);
    193   }
     195  }
     196  fclose (f);
    194197
    195198  if (!status) {
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/spline_construct.c

    r16119 r18424  
    1616  if ((out = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) return (FALSE);
    1717
     18  // XXX move this to gfits_create_matrix
    1819  free (out[0].matrix.buffer);
    19   free (out[0].header.buffer);
    2020  if ((in[0].file[0] != '*') && (in[0].file[0] != '(')) {
    2121    sprintf (out[0].file, "*%s", in[0].file);
  • branches/eam_branch_20080421/Ohana/src/opihi/cmd.data/wd.c

    r15487 r18424  
    8181  memcpy (temp_header.buffer, buf[0].header.buffer, temp_header.size);
    8282
    83   if (temp_header.Naxes) gfits_convert_format (&temp_header, &temp_matrix, outBitpix, outScale, outZero, outUnsign);
     83  if (temp_header.Naxes) {
     84    gfits_convert_format (&temp_header, &temp_matrix, outBitpix, outScale, outZero, outUnsign);
     85  } else {
     86    gfits_modify (&temp_header, "BITPIX", "%d", 1, outBitpix);
     87    gfits_modify (&temp_header, "BSCALE", "%lf", 1, outScale);
     88    gfits_modify (&temp_header, "BZERO",  "%lf", 1, outZero);
     89    gfits_modify (&temp_header, "UNSIGN", "%t", 1, outUnsign);
     90  }
    8491
    8592  if (Extend) {
  • branches/eam_branch_20080421/Ohana/src/opihi/dvo/ImageOps.c

    r14590 r18424  
    5050    if (selection->useDisplay) {
    5151      if (!FindMosaicForImage (image, Nimage, i)) continue;
     52      // first check if region center is in image
     53      status = RD_to_XY (&X, &Y, Rmid, graph.coords.crval2, &image[i].coords);
     54      if (status && (X >= 0) && (X < image[i].NX) && (Y >= 0) && (Y < image[i].NY)) goto in_region;
     55
    5256      /* project this image to screen display coords */
    5357      x[0] = 0;           y[0] = 0;
  • branches/eam_branch_20080421/Ohana/src/opihi/dvo/dbExtractMeasures.c

    r17469 r18424  
    291291      break;
    292292    case MEAS_FWHM: /* OK */
    293       value = 0.01*(measure[0].FWx + measure[0].FWy);
     293      value = 0.01*(measure[0].FWx + measure[0].FWy) / 2.0;
    294294      break;
    295295    case MEAS_FWHM_MAJ: /* OK */
  • branches/eam_branch_20080421/Ohana/src/opihi/include/pcontrol.h

    r17469 r18424  
    88/** job status values **/
    99typedef enum {
     10  PCONTROL_JOB_ALLJOBS,
    1011  PCONTROL_JOB_PENDING,
    1112  PCONTROL_JOB_BUSY, 
     13  PCONTROL_JOB_RESP, 
    1214  PCONTROL_JOB_HUNG, 
    1315  PCONTROL_JOB_DONE, 
     
    2628/** host status values **/
    2729typedef enum {
     30  PCONTROL_HOST_ALLHOSTS,
    2831  PCONTROL_HOST_IDLE,
    2932  PCONTROL_HOST_BUSY, 
     33  PCONTROL_HOST_RESP,
    3034  PCONTROL_HOST_DOWN,
    3135  PCONTROL_HOST_DONE,
    3236  PCONTROL_HOST_OFF,
    3337} HostStat;
     38
     39/** host response options **/
     40typedef enum {
     41  PCONTROL_RESP_NONE,
     42  PCONTROL_RESP_START_JOB,
     43  PCONTROL_RESP_CHECK_BUSY_JOB, 
     44  PCONTROL_RESP_CHECK_DONE_HOST, 
     45  PCONTROL_RESP_CHECK_HOST,
     46  PCONTROL_RESP_KILL_JOB,
     47  PCONTROL_RESP_STOP_HOST,
     48} HostResp;
    3449
    3550typedef enum {
     
    97112  Ptime       nexttry;
    98113  IDtype      HostID;
     114  IOBuffer    comms_buffer;
     115  char       *response;
     116  HostResp    response_state;
    99117  struct Job *job;
    100118} Host;
     
    156174
    157175/*** own files ***/
     176int StartJob (Job *job, Host *host);
     177int StartJobResponse (Host *host);
     178
    158179int CheckHost (Host *host);
     180int CheckHostResponse (Host *host);
     181
     182int CheckDoneHost (Host *host);
     183int CheckDoneHostResponse (Host *host);
     184
     185int CheckBusyJob (Job *job, Host *host);
     186int CheckBusyJobResponse (Host *host);
     187
     188int KillJob (Job *job, Host *host);
     189int KillJobResponse (Host *host);
     190
    159191int StartHost (Host *host);
    160192int CheckIdleHost (Host *host);
    161 int CheckDoneHost (Host *host);
    162 int CheckBusyJob (Job *job, Host *host);
    163193int CheckDoneJob (Job *job, Host *host);
    164 int KillJob (Job *job, Host *host);
    165 int StartJob (Job *job, Host *host);
    166 int ResetJob (Job *job);
    167194int GetJobOutput (char *command, Host *host, IOBuffer *buffer, int Nbytes);
    168 int PclientCommand (Host *host, char *command, char *response, IOBuffer *buffer);
    169195int rconnect (char *command, char *hostname, char *shell, int *stdio);
     196
     197int PclientCommand (Host *host, char *command, char *response, HostResp response_state);
     198int PclientResponse (Host *host, char *response, IOBuffer *buffer);
     199
     200int CheckRespHosts (float MaxDelay);
     201int CheckRespHost (Host *host);
    170202
    171203/*** misc files ***/
     
    178210IDtype NextHostID ();
    179211void PrintID (gpDest dest, IDtype ID);
     212IDtype GetID (char *IDword);
    180213
    181214/*** CheckPoint.c ***/
     
    203236int    DownHosts ();
    204237int    StopHost (Host *host);
     238int    StopHostResponse (Host *host);
    205239int    HarvestHost (int pid);
    206240
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.data/fft.c

    r16107 r18424  
    127127    Nminor *= Nsize[iDim];
    128128  }
     129  free (Nbit);
    129130  free (tmpX);
    130131  free (tmpY);
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.data/open_kapa.c

    r16435 r18424  
    108108
    109109    if (!strncmp (kapa_exec, "unix://", 7)) {
    110         fd = KapaOpenNamedSocket (&kapa_exec[7], "psphot");
     110        fd = KapaOpenNamedSocket (&kapa_exec[7], kapa_name);
    111111    } else {
    112112        fd = KapaOpen (kapa_exec, kapa_name);
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.shell/BufferOps.c

    r16886 r18424  
    122122
    123123int CopyBuffer (Buffer *out, Buffer *in) {
    124   free (out[0].matrix.buffer);
    125   free (out[0].header.buffer);
    126124  out[0].bitpix = in[0].bitpix;
    127125  out[0].unsign = in[0].unsign;
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.shell/evaluate_stack.c

    r16890 r18424  
    1313 
    1414  int i, j, Nvar, Nout, status;
    15   char line[512];
     15  char line[512]; // this is only used to report an error
    1616  StackVar tmp_stack;
    1717  Nout = Nvar = 0;
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.shell/multicommand.c

    r16903 r18424  
    9393
    9494          // receive the command exit status
    95           if (ExpectMessage (server, 2.0, &message)) {
     95          if (ExpectMessage (server, 10.0, &message)) {
    9696            switch (errno) {
    9797              case EPIPE:
     
    108108
    109109          // receive the resulting stderr
    110           if (ExpectMessage (server, 2.0, &message)) {
     110          if (ExpectMessage (server, 10.0, &message)) {
    111111            switch (errno) {
    112112              case EPIPE:
     
    123123
    124124          // receive the resulting stdout
    125           if (ExpectMessage (server, 2.0, &message)) {
     125          if (ExpectMessage (server, 10.0, &message)) {
    126126            switch (errno) {
    127127              case EPIPE:
  • branches/eam_branch_20080421/Ohana/src/opihi/lib.shell/stack_math.c

    r17470 r18424  
    1010  int i, Nx;
    1111  float *out, *M1, *M2;
    12   char line[512];
     12  char line[512]; // this is only used to report an error
    1313 
    1414  Nx = V1[0].vector[0].Nelements;
     
    8383  switch (op[0]) {
    8484  case '+':
    85     VV_FUN
    86    
     85    VV_FUNC
    8786
    8887    if ((M1->type == OPIHI_FLOAT) && (M2->type == OPIHI_FLOAT)) {
     
    222221  int i, Nx;
    223222  float *out, *M1, *M2;
    224   char line[512];
     223  char line[512]; // this is only used to report an error
    225224 
    226225  Nx = V2[0].vector[0].Nelements;
     
    340339  int i, Nx;
    341340  float *out, *M1, *M2;
    342   char line[512];
     341  char line[512]; // this is only used to report an error
    343342 
    344343  Nx = V1[0].vector[0].Nelements;
     
    459458  int i, j, Nx, Ny;
    460459  float *out, *M1, *M2;
    461   char line[512];
     460  char line[512]; // this is only used to report an error
    462461 
    463462  Nx = V1[0].buffer[0].matrix.Naxis[0];
     
    629628  int i, j, Nx, Ny;
    630629  float *out, *M1, *M2;
    631   char line[512];
     630  char line[512]; // this is only used to report an error
    632631 
    633632  Nx = V2[0].buffer[0].matrix.Naxis[0];
     
    815814  int i, Nx, Ny;
    816815  float *out, *M1, *M2;
    817   char line[512];
     816  char line[512]; // this is only used to report an error
    818817 
    819818  Nx = V1[0].buffer[0].matrix.Naxis[0];
     
    947946  int i, Nx, Ny;
    948947  float *out, *M1, *M2;
    949   char line[512];
     948  char line[512]; // this is only used to report an error
    950949 
    951950  Nx = V1[0].buffer[0].matrix.Naxis[0];
     
    10661065  int i, Nx, Ny;
    10671066  float *out, *M1, *M2;
    1068   char line[512];
     1067  char line[512]; // this is only used to report an error
    10691068 
    10701069  Nx = V2[0].buffer[0].matrix.Naxis[0];
     
    11831182
    11841183  float *M1, *M2, *out;
    1185   char line[512];
     1184  char line[512]; // this is only used to report an error
    11861185
    11871186  M1  = V1[0].ptr;
     
    12671266
    12681267  int value;
    1269   char line[512];
     1268  char line[512]; // this is only used to report an error
    12701269
    12711270  /* only 'N' and 'E' are allowed for WW_binary operations. anything else is either a
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/ControllerOps.c

    r13581 r18424  
    11# include "pantasks.h"
    22/* adding a new host can delay controller up to a second or so */
    3 # define CONTROLLER_TIMEOUT 1000
    4 # define CONNECT_TIMEOUT 300
     3# define CONTROLLER_TIMEOUT 5000
     4# define CONNECT_TIMEOUT 1000
    55
    66/* local static variables to hold the connection to the controller */
     
    8888  /** parse status message **/
    8989  p = memstr (buffer.buffer, "STATUS",   buffer.Nbuffer);
     90  if (p == NULL) goto escape;
    9091  sscanf (p, "%*s %s", status_string);
    9192  p = memstr (buffer.buffer, "EXITST",   buffer.Nbuffer);
     93  if (p == NULL) goto escape;
    9294  sscanf (p, "%*s %d", &job[0].exit_status);
    9395  p = memstr (buffer.buffer, "STDOUT",   buffer.Nbuffer);
     96  if (p == NULL) goto escape;
    9497  sscanf (p, "%*s %d", &job[0].stdout_size);
    9598  p = memstr (buffer.buffer, "STDERR",   buffer.Nbuffer);
     99  if (p == NULL) goto escape;
    96100  sscanf (p, "%*s %d", &job[0].stderr_size);
    97101  p = memstr (buffer.buffer, "DTIME",    buffer.Nbuffer);
     102  if (p == NULL) goto escape;
    98103  sscanf (p, "%*s %lf", &job[0].dtime);
    99104  p = memstr (buffer.buffer, "HOSTNAME", buffer.Nbuffer);
     105  if (p == NULL) goto escape;
    100106  sscanf (p, "%*s %s", string);
    101107  job[0].realhost = strcreate (string);
     
    109115  if (!strcmp(status_string, "EXIT"))    outstate = JOB_EXIT;
    110116  if (!strcmp(status_string, "CRASH"))   outstate = JOB_CRASH;
    111   if (outstate == -1) {
    112     gprint (GP_ERR, "programming error?\n");
    113     exit (1);
    114   }
     117  if (outstate == -1) goto escape;
     118
    115119  job[0].state = outstate;
    116120  return (TRUE);
     121
     122  escape:
     123  gprint (GP_ERR, "garbage in pcontrol reponse\n");
     124  FreeIOBuffer (&buffer);
     125  return (FALSE);
    117126}
    118127
     
    297306    status = ReadtoIOBuffer (&buffer, stdout_fd[0]);
    298307    p = memstr (buffer.buffer, "CONNECTED", buffer.Nbuffer);
    299     usleep (10000); // wait for controller to start up
     308    usleep (50000); // wait for controller to start up
    300309  }
    301310  if (status == 0) goto pipe_error;
     
    436445}
    437446
     447int FlushControllerOutput () {
     448
     449  FlushIOBuffer (&stdout_buffer);
     450  FlushIOBuffer (&stderr_buffer);
     451
     452  return (TRUE);
     453}
    438454
    439455int KillControllerJob (Job *job) {
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/JobOps.c

    r16451 r18424  
    1616}
    1717
     18/* free all jobs, only used on shutdown */
    1819void FreeJobs () {
    1920  int i;
     
    159160  if (task[0].stderr_dump != NULL) job[0].stderr_dump = strcreate (task[0].stderr_dump);
    160161
     162  job[0].stdout_fd = -1;
     163  job[0].stderr_fd = -1;
     164
    161165  jobs[Njobs] = job;
    162166  Njobs ++;
     
    185189  }
    186190  free (job[0].optv);
     191
     192  if (job[0].stdout_fd >= 0) close (job[0].stdout_fd);
     193  if (job[0].stderr_fd >= 0) close (job[0].stderr_fd);
    187194
    188195  if (job[0].stdout_dump != NULL) free (job[0].stdout_dump);
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/LocalJob.c

    r15875 r18424  
    2121    close (job[0].stdout_fd);
    2222    close (job[0].stderr_fd);
     23    job[0].stdout_fd = -1; // prevent FreeJob from trying to close again
     24    job[0].stderr_fd = -1; // prevent FreeJob from trying to close again
    2325  } else {
    2426    /* read stdout buffer */
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/Makefile

    r16903 r18424  
    7979$(SRC)/controller_status.$(ARCH).o \
    8080$(SRC)/controller_jobstack.$(ARCH).o \
     81$(SRC)/controller_verbose.$(ARCH).o \
    8182$(SRC)/controller_run.$(ARCH).o \
    8283$(SRC)/controller_output.$(ARCH).o \
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/controller.c

    r16463 r18424  
    55int controller_status   PROTO((int, char **));
    66int controller_jobstack PROTO((int, char **));
     7int controller_verbose  PROTO((int, char **));
    78int controller_run      PROTO((int, char **));
    89int controller_stop     PROTO((int, char **));
     
    1920  {1, "status",   controller_status,   "check controller status"},
    2021  {1, "jobstack", controller_jobstack, "check controller status"},
     22  {1, "verbose",  controller_verbose,  "set controller verbosity"},
    2123  {1, "output",   controller_output,   "print controller output"},
    2224  {1, "pulse",    controller_pulse,    "set controller pulse"},
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/controller_jobstack.c

    r14590 r18424  
    2121
    2222  // XXX this has an error?  test this out...
    23   sprintf (command, "jobstack %s", argv[2]);
     23  sprintf (command, "jobstack %s", argv[1]);
    2424  InitIOBuffer (&buffer, 0x100);
    2525
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/controller_output.c

    r7917 r18424  
    33int controller_output (int argc, char **argv) {
    44
    5   if (argc != 1) {
    6     gprint (GP_ERR, "USAGE: controller status\n");
     5  if ((argc != 1) || ((argc == 2) && (strcmp(argv[1], "flush")))) {
     6    gprint (GP_ERR, "USAGE: controller output\n");
    77    return (FALSE);
    88  }
     
    1010  CheckControllerOutput ();
    1111  PrintControllerOutput ();
     12
     13  if (argc == 2) {
     14    FlushControllerOutput ();
     15  }
     16
    1217  return (TRUE);
    1318}
  • branches/eam_branch_20080421/Ohana/src/opihi/pantasks/ipptool2book.c

    r16810 r18424  
    1111  int i, N, onPage, found, Unique, Nkeys, NKEYS;
    1212  char *line, *tmpword, *tmpvalue;
    13   char pagename[512], *bookName, **keys, *p, *q;
     13  char pagename[512]; // XXX this should be made dynamic, though it is an unlikey problem
     14  char *bookName, **keys, *p, *q;
    1415  char **setWordList;
    1516  char **setWordValue;
     
    102103  tmpword = nextword (line);
    103104
    104   if (strcmp(tmpword, "MULTI")) {
     105  if (!tmpword || strcmp(tmpword, "MULTI")) {
    105106    gprint (GP_ERR, "ERROR: missing metadata output name on first line\n");
    106107    free (bookName);
  • branches/eam_branch_20080421/Ohana/src/opihi/pclient/pclient.c.in

    r16455 r18424  
    2323  rl_attempted_completion_function = command_completer;
    2424  rl_event_hook = CheckChild;
    25   rl_set_keyboard_input_timeout (1000);
     25  rl_set_keyboard_input_timeout (20000);
    2626  /* 1 ms seems to be the minimum valid number */
    2727
     
    6363  FreeBasic ();
    6464  FreePclient ();
     65  gprint (GP_LOG, "Goodbye\n");
    6566  return;
    6667}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/CheckBusyJob.c

    r16456 r18424  
    44int CheckBusyJob (Job *job, Host *host) {
    55
    6   int      status;
    7   int      outstate;
    8   char    *p;
    9   char     string[64];
    10   IOBuffer buffer;
     6  int status;
    117
    128  /* we are checking a job which is currently busy.  it has been pulled from the
     
    1612  ASSERT (job, "job not set");
    1713  ASSERT (host, "host not set");
    18 
    1914  ASSERT (host == (Host *) job[0].host, "invalid host");
    2015  ASSERT (job  == (Job *) host[0].job, "invalid job");
    2116
    22   InitIOBuffer (&buffer, 0x100);
    23 
    24   status = PclientCommand (host, "status", PCLIENT_PROMPT, &buffer);
     17  status = PclientCommand (host, "status", PCLIENT_PROMPT, PCONTROL_RESP_CHECK_BUSY_JOB);
    2518
    2619  /* check on success of pclient command */
    2720  switch (status) {
    2821    case PCLIENT_DOWN:
    29       HarvestHost (host[0].pid);
     22      // free the realhost name
     23      if (job[0].realhost) free (job[0].realhost);
     24      job[0].realhost = NULL;
     25
    3026      // unlink host & job
     27      if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    3128      job[0].host = NULL;
    3229      host[0].job = NULL;
    33       if (job[0].realhost) free (job[0].realhost);
    34       job[0].realhost = NULL;
     30      HarvestHost (host[0].pid);
    3531      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    3632      PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
    37       FreeIOBuffer (&buffer);
    3833      return (FALSE);
    39 
    40     case PCLIENT_HUNG:
    41       // don't do anything drastic, just keep trying
    42       if (DEBUG || VerboseMode()) gprint (GP_ERR, "client is busy, not responding");
    43       PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
    44       PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
    45       FreeIOBuffer (&buffer);
    46       return (TRUE);
    4734
    4835    case PCLIENT_GOOD:
    4936      if (DEBUG || VerboseMode()) gprint (GP_ERR, "message received (CheckBusyJob)");
    50       break;
     37      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     38      PutJob (job, PCONTROL_JOB_RESP, STACK_BOTTOM);
     39      return (TRUE);
    5140
    5241    default:
    5342      ABORT ("unknown status for pclient command"); 
    5443  }
     44}
     45
     46int CheckBusyJobResponse (Host *host) {
     47
     48  int      outstate;
     49  char    *p;
     50  char     string[64];
     51  IOBuffer *buffer;
     52  Job *job;
     53
     54  /* job must have assigned host */
     55  ASSERT (host, "missing host");
     56  ASSERT (host[0].job, "missing job");
     57  buffer = &host[0].comms_buffer;
     58  job = (Job *) host[0].job;
    5559
    5660  /** host is up, need to parse message **/
    57   p = memstr (buffer.buffer, "STATUS", buffer.Nbuffer);
    58   // this condition means the message is garbage.  toss it and try again
     61  p = memstr (buffer[0].buffer, "STATUS", buffer[0].Nbuffer);
    5962  if (p == NULL) {
    60     PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
    61     PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
    62     FreeIOBuffer (&buffer);
    63     return (FALSE);
     63      if (DEBUG || VerboseMode()) gprint (GP_ERR, "missing STATUS in response; try again\n");
     64      PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
     65      PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
     66      return (TRUE);
    6467  }
    6568
     
    7174    PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
    7275    PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
    73     FreeIOBuffer (&buffer);
    7476    return (TRUE);
    7577  }
     
    7981  if (!strcmp(string, "EXIT")) outstate = PCONTROL_JOB_EXIT;
    8082  if (!strcmp(string, "CRASH")) outstate = PCONTROL_JOB_CRASH;
    81   ASSERT (outstate != PCONTROL_JOB_BUSY, "should not reach here (CheckJob)");
     83  ASSERT (outstate != PCONTROL_JOB_BUSY, "invalid status response (CheckBusyJobResponse)");
    8284
    8385  /* parse the exit status and sizes of output buffers */
    84   p = memstr (buffer.buffer, "EXITST", buffer.Nbuffer);
     86  p = memstr (buffer[0].buffer, "EXITST", buffer[0].Nbuffer);
    8587  sscanf (p, "%*s %d", &job[0].exit_status);
    86   p = memstr (buffer.buffer, "STDOUT", buffer.Nbuffer);
     88  p = memstr (buffer[0].buffer, "STDOUT", buffer[0].Nbuffer);
    8789  sscanf (p, "%*s %d", &job[0].stdout_size);
    88   p = memstr (buffer.buffer, "STDERR", buffer.Nbuffer);
     90  p = memstr (buffer[0].buffer, "STDERR", buffer[0].Nbuffer);
    8991  sscanf (p, "%*s %d", &job[0].stderr_size);
    9092
     
    98100  PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
    99101  PutJobSetState (job, PCONTROL_JOB_DONE, STACK_BOTTOM, outstate);
    100   gettimeofday (&job[0].stop, (void *) NULL);
     102  gettimeofday (&job[0].stop, NULL);
    101103  job[0].dtime = DTIME(job[0].stop, job[0].start);
    102   FreeIOBuffer (&buffer);
    103104  return (TRUE);
    104105}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/CheckDoneHost.c

    r10668 r18424  
    55 
    66  int       status;
    7   char     *p;
    8   IOBuffer  buffer;
    97
    108  ASSERT (host, "host not set");
    119
    12   InitIOBuffer (&buffer, 0x100);
    13  
    14   status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);
     10  status = PclientCommand (host, "reset", PCLIENT_PROMPT, PCONTROL_RESP_CHECK_DONE_HOST);
    1511
    1612  /* check on success of pclient command */
     
    1814    case PCLIENT_DOWN:
    1915      if (DEBUG || VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    20       /* DONE host does not have an incomplete job */
    2116      HarvestHost (host[0].pid);
    2217      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    23       FreeIOBuffer (&buffer);
    2418      return (FALSE);
     19      /* DONE host does not have an incomplete job */
    2520      // XXX do we need to close the connection?
    2621
    27     case PCLIENT_HUNG:
    28       // don't do anything drastic, just try again later
    29       PutHost (host, PCONTROL_HOST_DONE, STACK_BOTTOM);
    30       if (DEBUG || VerboseMode()) gprint (GP_ERR, "host %s is not responding\n", host[0].hostname);
    31       FreeIOBuffer (&buffer);
    32       return (FALSE);
    33 
    3422    case PCLIENT_GOOD:
    35       if (VerboseMode()) gprint (GP_ERR, "message received (CheckDoneHost)\n"); 
    36       break;
     23      if (VerboseMode()) gprint (GP_ERR, "checking done host %s\n", host[0].hostname); 
     24      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     25      return (TRUE);
    3726
    3827    default:
    3928      ABORT ("unknown status for pclient command"); 
    4029  }
     30  ABORT ("should not reach here (CheckDoneHost)");
     31}
     32
     33int CheckDoneHostResponse (Host *host) {
     34
     35  int status;
     36  char *p;
     37  IOBuffer *buffer;
     38
     39  /* job must have assigned host */
     40  ASSERT (host, "missing host");
     41  buffer = &host[0].comms_buffer;
    4142
    4243  /** successful command, examine result **/
    43   p = memstr (buffer.buffer, "STATUS", buffer.Nbuffer);
    44   ASSERT (p != NULL, "missing STATUS in pclient message (CheckDoneHost)");
     44  p = memstr (buffer[0].buffer, "STATUS", buffer[0].Nbuffer);
     45  if (p == NULL) {
     46      if (DEBUG || VerboseMode()) gprint (GP_ERR, "missing STATUS in response; try again\n");
     47      PutHost (host, PCONTROL_HOST_DONE, STACK_BOTTOM);
     48      return (FALSE);
     49  }
    4550
    4651  sscanf (p, "%*s %d", &status);
     
    5257      if (DEBUG || VerboseMode()) gprint (GP_ERR, "reset failed\n");
    5358      PutHost (host, PCONTROL_HOST_DONE, STACK_BOTTOM);
    54       FreeIOBuffer (&buffer);
    5559      return (FALSE);
    5660     
     
    5963      if (DEBUG || VerboseMode()) gprint (GP_ERR, "successful reset\n");
    6064      PutHost (host, PCONTROL_HOST_IDLE, STACK_BOTTOM);
    61       FreeIOBuffer (&buffer);
    6265      return (FALSE);
    6366
     
    6770  ABORT ("should not reach here (CheckDoneHost)");
    6871}
    69 
    70 /** probably need to flush the buffer before the command **/
    71 /** need to add timeout check here **/
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/CheckHost.c

    r10652 r18424  
    11# include "pcontrol.h"
    22
     3// if the host has a job, we skip it (down or crash state will be caught elsewhere)
     4// in fact, just touch the IDLE hosts, not the BUSY hosts?
    35int CheckHost (Host *host) {
    46 
    57  int status;
    6   IOBuffer buffer;
    78
    89  ASSERT (host, "host not set");
     
    1415    host[0].markoff = FALSE;
    1516    StopHost (host);
    16     OffHost (host);
    1717    return (TRUE);
    1818  }
    1919
    20   InitIOBuffer (&buffer, 0x100);
     20  // the argument to echo (OK) is the expected response below in CheckHostResponse
     21  status = PclientCommand (host, "echo OK", PCLIENT_PROMPT, PCONTROL_RESP_CHECK_HOST);
    2122
    22   status = PclientCommand (host, "echo OK", PCLIENT_PROMPT, &buffer);
    2323  switch (status) {
    24     case 0:
     24    case PCLIENT_DOWN:
    2525      if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    2626      HarvestHost (host[0].pid);
    2727      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    28       FreeIOBuffer (&buffer);
    2928      return (FALSE);
    3029     
    31     case -1:
    32       if (VerboseMode()) gprint (GP_ERR, "host %s is not responding\n", host[0].hostname);
    33       /*** do we mark this in some way (HUNG) ? ***/
    34       PutHost (host, host[0].stack, STACK_BOTTOM);
    35       FreeIOBuffer (&buffer);
    36       return (FALSE);
     30    case PCLIENT_GOOD:
     31      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     32      return (TRUE);
    3733
    3834    default:
    39       PutHost (host, host[0].stack, STACK_BOTTOM);
    40       FreeIOBuffer (&buffer);
    41       return (TRUE);
     35      ABORT ("unknown status for pclient command"); 
    4236  }
    43   ABORT ("should not reach here (Check Host)");
     37  ABORT ("should not reach here (CheckHost)");
    4438}
    4539
    46 // if the host has a job, we skip it (down or crash state will be caught elsewhere)
    47 // in fact, just touch the IDLE hosts, not the BUSY hosts?
     40int CheckHostResponse (Host *host) {
     41 
     42  IOBuffer *buffer;
     43
     44  /* we only check IDLE hosts without jobs */
     45  ASSERT (host, "missing host");
     46  buffer = &host[0].comms_buffer;
     47
     48  // XXX check on the value of the response? (OK)
     49
     50  PutHost (host, PCONTROL_HOST_IDLE, STACK_BOTTOM);
     51  return (TRUE);
     52}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/CheckIdleHost.c

    r10667 r18424  
    1414    host[0].markoff = FALSE;
    1515    StopHost (host);
    16     OffHost (host);
    1716    return (TRUE);
    1817  }
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/CheckSystem.c

    r16589 r18424  
    9999
    100100    if (RunLevel != PCONTROL_RUN_NONE) {
     101      Nhostchecks += CheckRespHosts(0.020); /* check for incoming messages */
     102      TestCheckPoint ();
    101103      Nhostchecks += CheckDoneHosts(0.020); /* reset the host */
    102104      TestCheckPoint ();
     
    258260}
    259261
     262int CheckRespHosts (float MaxDelay) {
     263
     264  struct timeval start, stop;
     265  int i, Nobject;
     266  Stack *hoststack;
     267  Stack *jobstack;
     268  Host *host;
     269  Job *job;
     270  float dtime;
     271
     272  /* Loop through objects on the stack, no more than once. see note above */
     273  hoststack = GetHostStack (PCONTROL_HOST_RESP);
     274  jobstack = GetJobStack (PCONTROL_JOB_RESP);
     275  Nobject = hoststack[0].Nobject;
     276
     277  /* always allow at least one test */
     278  gettimeofday (&start, (void *) NULL);
     279  dtime = 0.0;
     280  for (i = 0; (i < Nobject) && (dtime < MaxDelay); i++) {
     281    LockStack (jobstack);
     282    host = PullStackByLocation (hoststack, STACK_TOP);
     283    if (host == NULL) {
     284        UnlockStack (jobstack);
     285        break;
     286    }
     287
     288    // if the host has a job, we need to pull the job from its stack
     289    job = (Job *) host[0].job;
     290    if (job != NULL) {
     291        RemoveStackByID (jobstack, job[0].JobID);
     292    }
     293    UnlockStack (jobstack);
     294
     295    CheckRespHost (host);
     296    gettimeofday (&stop, (void *) NULL);
     297    dtime = DTIME (stop, start);
     298  }
     299  if (DEBUG) gprint (GP_ERR, "checked %d hosts\n", i);
     300  return (i);
     301}
     302
    260303int CheckDoneHosts (float MaxDelay) {
    261304
     
    303346    if (host == NULL) break;
    304347    if (host[0].markoff) {
     348      // DOWN -> OFF
    305349      host[0].markoff = FALSE;
    306350      OffHost (host);
     
    311355      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    312356    } else {
     357      // DOWN -> IDLE (maybe)
     358      // this is a race condition with "host retry", but the only
     359      // consequence is that both StartHost and reset set the times to 0.0
    313360      StartHost (host);
    314361    }
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/HostOps.c

    r16472 r18424  
    11# include "pcontrol.h"
    22
    3 Stack *HostPool_Idle;
    4 Stack *HostPool_Busy;
    5 Stack *HostPool_Done;
    6 Stack *HostPool_Down;
    7 Stack *HostPool_Off;
     3Stack *HostPool_AllHosts;  // virtual pool for user status queries
     4
     5Stack *HostPool_Idle; // these hosts are waiting for something to do
     6Stack *HostPool_Busy; // these hosts are working
     7Stack *HostPool_Resp; // these hosts are trying to respond
     8Stack *HostPool_Done; // these hosts have finished a job
     9Stack *HostPool_Down; // these hosts are not responding
     10Stack *HostPool_Off;  // these hosts are off
    811
    912void InitHostStacks () {
     13  HostPool_AllHosts = InitStack ();
     14
    1015  HostPool_Idle = InitStack ();
    1116  HostPool_Busy = InitStack ();
     17  HostPool_Resp = InitStack ();
    1218  HostPool_Done = InitStack ();
    1319  HostPool_Down = InitStack ();
     
    2632  FreeHostStack (HostPool_Idle);
    2733  FreeHostStack (HostPool_Busy);
     34  FreeHostStack (HostPool_Resp);
    2835  FreeHostStack (HostPool_Done);
    2936  FreeHostStack (HostPool_Down);
    3037  FreeHostStack (HostPool_Off );
     38
     39  // AllHosts is a virtual stack : all hosts are references
     40  FreeStack (HostPool_AllHosts);
    3141}
    3242
    3343char *GetHostStackName (int StackID) {
    3444  switch (StackID) {
     45    case PCONTROL_HOST_ALLHOSTS: return ("ALLHOSTS");
    3546    case PCONTROL_HOST_IDLE: return ("IDLE");
    3647    case PCONTROL_HOST_DOWN: return ("DOWN");
     48    case PCONTROL_HOST_RESP: return ("RESP");
    3749    case PCONTROL_HOST_DONE: return ("DONE");
    3850    case PCONTROL_HOST_BUSY: return ("BUSY");
     
    4658Stack *GetHostStack (int StackID) {
    4759  switch (StackID) {
     60    case PCONTROL_HOST_ALLHOSTS: return (HostPool_AllHosts);
    4861    case PCONTROL_HOST_IDLE: return (HostPool_Idle);
    4962    case PCONTROL_HOST_DOWN: return (HostPool_Down);
     63    case PCONTROL_HOST_RESP: return (HostPool_Resp);
    5064    case PCONTROL_HOST_DONE: return (HostPool_Done);
    5165    case PCONTROL_HOST_BUSY: return (HostPool_Busy);
     
    5872
    5973Stack *GetHostStackByName (char *name) {
     74  if (!strcasecmp (name, "all")) return (HostPool_AllHosts);
    6075  if (!strcasecmp (name, "idle")) return (HostPool_Idle);
    6176  if (!strcasecmp (name, "down")) return (HostPool_Down);
     77  if (!strcasecmp (name, "resp")) return (HostPool_Resp);
    6278  if (!strcasecmp (name, "done")) return (HostPool_Done);
    6379  if (!strcasecmp (name, "busy")) return (HostPool_Busy);
     
    7187  int stat;
    7288  Stack *stack;
     89
     90  // fprintf (stderr, "move host %s to %s\n", host[0].hostname, GetHostStackName(StackID));
    7391
    7492  stack = GetHostStack (StackID);
     
    94112  if (host != NULL) return (host);
    95113
     114  *StackID = PCONTROL_HOST_RESP;
     115  host = PullHostFromStackByID (*StackID, HostID);
     116  if (host != NULL) return (host);
     117
    96118  *StackID = PCONTROL_HOST_DONE;
    97119  host = PullHostFromStackByID (*StackID, HostID);
     
    120142
    121143  *StackID = PCONTROL_HOST_DOWN;
     144  host = PullHostFromStackByName (*StackID, name);
     145  if (host != NULL) return (host);
     146
     147  *StackID = PCONTROL_HOST_RESP;
    122148  host = PullHostFromStackByName (*StackID, name);
    123149  if (host != NULL) return (host);
     
    180206  host[0].nexttry.tv_usec = 0;
    181207
     208  InitIOBuffer (&host[0].comms_buffer, 0x100);
     209  host[0].response_state = PCONTROL_RESP_NONE;
     210  host[0].response = NULL;
     211
    182212  host[0].markoff  = FALSE;
    183213  host[0].job      = NULL;
     214
     215  PutHost (host, PCONTROL_HOST_ALLHOSTS, STACK_BOTTOM);
    184216  PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    185217  return (host[0].HostID);
     
    187219
    188220void DelHost (Host *host) {
     221
     222  Host *copy;
     223
     224  copy = PullStackByID (HostPool_AllHosts, host[0].HostID);
     225  ASSERT (copy == host, "programming error: ALLHOSTS entry does not match");
     226
     227  FreeIOBuffer (&host[0].comms_buffer);
    189228  FREE (host[0].hostname);
    190229  FREE (host[0].job);
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/IDops.c

    r8296 r18424  
    11# include "pcontrol.h"
    22
    3 static IDtype CurrentJobID  = 0;
    4 static IDtype CurrentHostID = 0;
     3static IDtype CurrentJobID  = 1;
     4static IDtype CurrentHostID = 1;
    55
    6 /* for now, no persistence : we could use the date/time to seed the upper byte(s) if needed */
     6/* for now, no persistence between sessions : we could use the date/time to seed the upper
     7 * byte(s) if needed */
    78void InitIDs () {
    8   CurrentJobID = 0;
    9   CurrentHostID = 0;
     9  CurrentJobID = 1;
     10  CurrentHostID = 1;
    1011}
    1112
     
    4142}
    4243
     44IDtype GetID (char *IDword) {
     45
     46  int Nargs;
     47  IDtype ID;
     48  unsigned int word0, word1, word2, word3;
     49  char *endptr;
     50
     51  Nargs = sscanf (IDword, "%x.%x.%x.%x", &word3, &word2, &word1, &word0);
     52  if (Nargs == 4) {
     53      IDtype tmp;
     54    ID = 0;
     55    ID |= (word0 << 0);
     56    ID |= (word1 << 16);
     57    tmp = word2;
     58    ID |= (tmp << 32);
     59    tmp = word3;
     60    ID |= (tmp << 48);
     61    return ID;
     62  }
     63   
     64  ID = strtoll (IDword, &endptr, 10);
     65  if (*endptr == 0) {
     66    return ID;
     67  }
     68
     69  return 0;
     70}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/JobID.c

    r7917 r18424  
    4040}
    4141
     42IDtype GetID (char *IDword) {
     43
     44  int Nargs;
     45  IDtype ID;
     46  unsigned short int word0, word1, word2, word3;
     47
     48  Nargs = sscanf (IDword, "%x.%x.%x.%x", &word0, &word1, &word2, &word3);
     49  if (Nargs == 4) {
     50    ID = 0;
     51    ID |= (word0 << 0);
     52    ID |= (word1 << 16);
     53    ID |= (word2 << 32);
     54    ID |= (word3 << 48);
     55    return ID;
     56  }
     57   
     58  ID = strtoll (IDword, &endptr, 10);
     59  if (*endptr == 0) {
     60    return ID;
     61  }
     62
     63  return 0;
     64}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/JobOps.c

    r16472 r18424  
    11# include "pcontrol.h"
     2
     3Stack *JobPool_AllJobs;  // virtual pool for user status queries
    24
    35Stack *JobPool_Pending;
    46Stack *JobPool_Busy;
     7Stack *JobPool_Resp;
    58Stack *JobPool_Done;
    69Stack *JobPool_Kill;
     
    912
    1013void InitJobStacks () {
     14  JobPool_AllJobs = InitStack ();
     15
    1116  JobPool_Pending = InitStack ();
    1217  JobPool_Busy    = InitStack ();
     18  JobPool_Resp    = InitStack ();
    1319  JobPool_Done    = InitStack ();
    1420  JobPool_Kill    = InitStack ();
     
    2834  FreeJobStack (JobPool_Pending);
    2935  FreeJobStack (JobPool_Busy   );
     36  FreeJobStack (JobPool_Resp   );
    3037  FreeJobStack (JobPool_Done   );
    3138  FreeJobStack (JobPool_Kill   );
    3239  FreeJobStack (JobPool_Exit   );
    3340  FreeJobStack (JobPool_Crash  );
     41
     42  // AllJobs is a virtual stack : all jobs are references
     43  FreeStack (JobPool_AllJobs);
    3444}
    3545
    3646char *GetJobStackName (int StackID) {
    3747  switch (StackID) {
     48    case PCONTROL_JOB_ALLJOBS: return ("ALLJOBS");
     49
    3850    case PCONTROL_JOB_PENDING: return ("PENDING");
    3951    case PCONTROL_JOB_BUSY:    return ("BUSY");
     52    case PCONTROL_JOB_RESP:    return ("RESP");
    4053    case PCONTROL_JOB_DONE:    return ("DONE");
    4154    case PCONTROL_JOB_KILL:    return ("KILL");
     
    5063Stack *GetJobStack (int StackID) {
    5164  switch (StackID) {
     65    case PCONTROL_JOB_ALLJOBS: return (JobPool_AllJobs);
     66
    5267    case PCONTROL_JOB_PENDING: return (JobPool_Pending);
    5368    case PCONTROL_JOB_BUSY:    return (JobPool_Busy);
     69    case PCONTROL_JOB_RESP:    return (JobPool_Resp);
    5470    case PCONTROL_JOB_DONE:    return (JobPool_Done);
    5571    case PCONTROL_JOB_KILL:    return (JobPool_Kill);
     
    6480Stack *GetJobStackByName (char *name) {
    6581
     82  if (!strcasecmp (name, "all"))     return (JobPool_AllJobs);
     83
    6684  if (!strcasecmp (name, "pending")) return (JobPool_Pending);
    6785  if (!strcasecmp (name, "busy"))    return (JobPool_Busy);
     86  if (!strcasecmp (name, "resp"))    return (JobPool_Resp);
    6887  if (!strcasecmp (name, "done"))    return (JobPool_Done);
    6988  if (!strcasecmp (name, "exit"))    return (JobPool_Exit);
     
    7796  int stat;
    7897  Stack *stack;
     98
     99  // fprintf (stderr, "move job %s to %s\n", job[0].argv[0], GetJobStackName(StackID));
    79100
    80101  stack = GetJobStack (StackID);
     
    118139  if (job != NULL) return (job);
    119140
     141  *StackID = PCONTROL_JOB_RESP;
     142  job = PullJobFromStackByID (*StackID, JobID);
     143  if (job != NULL) return (job);
     144
    120145  *StackID = PCONTROL_JOB_EXIT;
    121146  job = PullJobFromStackByID (*StackID, JobID);
     
    160185  job[0].argv     = argv;
    161186  job[0].hostname = hostname;
     187  job[0].realhost = NULL;
     188
     189  job[0].exit_status = 0;
     190  job[0].Reset    = FALSE;
     191  job[0].stdout_size = 0;
     192  job[0].stderr_size = 0;
     193
    162194  job[0].mode     = mode;
    163   job[0].host     = NULL;
    164   job[0].JobID    = NextJobID();
    165   job[0].Reset    = FALSE;
    166   job[0].realhost = NULL;
     195
     196  job[0].state = 0;
     197  job[0].stack = 0;
    167198
    168199  /* do this step on start? */
     
    170201  InitIOBuffer (&job[0].stderr_buff, 0x1000);
    171202
     203  job[0].dtime = 0.0;
     204  job[0].pid = 0;
     205
     206  job[0].JobID    = NextJobID();
     207  job[0].host     = NULL;
     208
    172209  JobID = job[0].JobID;
     210
     211  // Put a copy of all created jobs on the ALLJOBS stack
     212  // This is a virtual stack: do not free the job from this stack
     213  PutJob (job, PCONTROL_JOB_ALLJOBS, STACK_BOTTOM);
    173214  PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
     215
    174216  if (VerboseMode()) gprint (GP_ERR, "added new job\n");
    175217  return (JobID);
     
    179221
    180222  int i;
     223
     224  Job *copy;
     225
     226  copy = PullStackByID (JobPool_AllJobs, job[0].JobID);
     227  ASSERT (copy == job, "programming error: ALLJOBS entry does not match");
    181228
    182229  FREE (job[0].hostname);
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/KillJob.c

    r10661 r18424  
    33int KillJob (Job *job, Host *host) {
    44 
    5   IOBuffer buffer;
    65  int status;
    7   char *p;
    86
    97  ASSERT (host != NULL, "host missing");
    108  ASSERT (job != NULL, "job missing");
    11 
    129  ASSERT (host == (Host *) job[0].host, "invalid host");
    1310  ASSERT (job  == (Job *) host[0].job, "invalid job");
    1411
    15   InitIOBuffer (&buffer, 0x100);
    16 
    17   status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);
     12  status = PclientCommand (host, "reset", PCLIENT_PROMPT, PCONTROL_RESP_KILL_JOB);
    1813
    1914  /* check on success of pclient command */
    2015  switch (status) {
    2116    case PCLIENT_DOWN:
    22       HarvestHost (host[0].pid);
    2317      // unlink host & job
     18      if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    2419      job[0].host = NULL;
    2520      host[0].job = NULL;
     21      HarvestHost (host[0].pid);
    2622      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    2723      PutJob (job, PCONTROL_JOB_CRASH, STACK_BOTTOM);
    28       FreeIOBuffer (&buffer);
    2924      return (FALSE);
    3025
    31     case PCLIENT_HUNG:
    32       // don't do anything drastic, just keep trying
    33       // XXX move to which stack??
    34       gprint (GP_ERR, "client is busy, not responding (KillJob)");
    35       FreeIOBuffer (&buffer);
     26    case PCLIENT_GOOD:
     27      if (VerboseMode()) gprint (GP_ERR, "kill job on host %s\n", host[0].hostname); 
     28      FlushIOBuffer (&host[0].comms_buffer);
     29      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     30      PutJob (job, PCONTROL_JOB_RESP, STACK_BOTTOM);
    3631      return (TRUE);
    37 
    38     case PCLIENT_GOOD:
    39       if (VerboseMode()) gprint (GP_ERR, "message received (KillJob)\n"); 
    40       break;
    4132
    4233    default:
    4334      ABORT ("unknown status for pclient command"); 
    4435  }
     36}
    4537
    46   /** host is up, need to parse message **/
    47   p = memstr (buffer.buffer, "STATUS", buffer.Nbuffer);
    48   ASSERT (p != NULL, "missing STATUS in pclient message");
    49   if (VerboseMode()) gprint (GP_ERR, "client message: %s\n", buffer.buffer);
     38int KillJobResponse (Host *host) {
     39 
     40  int status;
     41  char *p;
     42  IOBuffer *buffer;
     43  Job *job;
     44
     45  ASSERT (host != NULL, "host missing");
     46  ASSERT (host[0].job, "missing job");
     47  buffer = &host[0].comms_buffer;
     48  job = (Job *) host[0].job;
     49
     50  /** check on response to pclient command **/
     51  p = memstr (buffer[0].buffer, "STATUS", buffer[0].Nbuffer);
     52  if (p == NULL) {
     53      if (VerboseMode()) gprint (GP_ERR, "missing STATUS in response; try again\n");
     54      PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
     55      PutJob (job, PCONTROL_JOB_KILL, STACK_BOTTOM);
     56      return (FALSE);
     57  }
     58  if (VerboseMode()) gprint (GP_ERR, "client message: %s\n", buffer[0].buffer);
    5059
    5160  sscanf (p, "%*s %d", &status);
    52   FreeIOBuffer (&buffer);
    5361  gprint (GP_ERR, "client status: %d\n", status);
    5462
     
    6270      return (FALSE);
    6371    case 1:
    64       gprint (GP_ERR, "killing job %s on %s\n", job[0].argv[0], host[0].hostname);
     72      gprint (GP_ERR, "killed job %s on %s\n", job[0].argv[0], host[0].hostname);
    6573      // unlink host & job
    6674      job[0].host = NULL;
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/Makefile

    r12842 r18424  
    1313LIBS1         = -lkapa -lFITS -lohana
    1414LIBS2         = -lbasiccmd -lshell -ldata
    15 FULL_CFLAGS   = $(BASE_CFLAGS)
     15FULL_CFLAGS   = $(BASE_CFLAGS) -Wall -Werror
    1616FULL_CPPFLAGS = $(BASE_CPPFLAGS)
    1717FULL_LDFLAGS  = $(LIBS1) $(LIBS2) $(BASE_LDFLAGS)
     
    2727$(SRC)/CheckBusyJob.$(ARCH).o \
    2828$(SRC)/CheckDoneHost.$(ARCH).o \
     29$(SRC)/CheckRespHost.$(ARCH).o \
    2930$(SRC)/CheckDoneJob.$(ARCH).o \
    3031$(SRC)/CheckHost.$(ARCH).o \
     
    3839$(SRC)/StackOps.$(ARCH).o \
    3940$(SRC)/PclientCommand.$(ARCH).o \
    40 $(SRC)/ResetJob.$(ARCH).o \
    4141$(SRC)/StartHost.$(ARCH).o \
    4242$(SRC)/StopHosts.$(ARCH).o \
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/PclientCommand.c

    r16590 r18424  
    11# include "pcontrol.h"
    2 # define PCLIENT_TIMEOUT 5000
     2# define PCLIENT_TIMEOUT 100
    33
    4 int PclientCommand (Host *host, char *command, char *response, IOBuffer *buffer) {
     4// send a command and check for errors; ignore output
     5int PclientCommand (Host *host, char *command, char *response, HostResp response_state) {
    56
    6   int i;
    77  int status;
    8   char *line;
    9   struct timespec request, remain;
    108
    119  ASSERT (host != NULL, "host missing");
    12   ASSERT (buffer != NULL, "buffer missing");
    1310  ASSERT (command != NULL, "command missing");
    14   ASSERT (response != NULL, "response missing");
    15 
    16   /* avoid blocking on read, test every 100 usec, up to 50 msec */
    17   request.tv_sec = 0;
    18   request.tv_nsec = 100000;
    1911
    2012  // flush the stdout and stderr buffers here
    21   ReadtoIOBuffer (buffer, host[0].stdout_fd);
    22   FlushIOBuffer (buffer);
    23   ReadtoIOBuffer (buffer, host[0].stderr_fd);
    24   FlushIOBuffer (buffer);
     13  // recycle comms_buffer to minimize page thrashing
     14  ReadtoIOBuffer (&host[0].comms_buffer, host[0].stdout_fd);
     15  FlushIOBuffer (&host[0].comms_buffer);
     16  ReadtoIOBuffer (&host[0].comms_buffer, host[0].stderr_fd);
     17  FlushIOBuffer (&host[0].comms_buffer);
    2518
    2619  /* send command to client (adding on \n) */
     
    3326  }
    3427 
     28  // prepare host to accept response
     29  host[0].response_state = response_state;
     30  host[0].response = response;
     31  FlushIOBuffer (&host[0].comms_buffer);
     32
     33  // fprintf (stderr, "command: %s\n", command);
     34
     35  return (PCLIENT_GOOD);
     36}
     37 
     38// check for response; message must end with specified string.
     39// accumulate the response in the buffer
     40int PclientResponse (Host *host, char *response, IOBuffer *buffer) {
     41
     42  int i;
     43  int status;
     44  char *line;
     45  struct timespec request, remain;
     46
     47  ASSERT (response != NULL, "response missing");
     48  ASSERT (buffer != NULL, "buffer missing");
     49
     50  /* avoid blocking very long on read, test every 100 usec, up to 0.1 sec */
     51  request.tv_sec = 0;
     52  request.tv_nsec = 100000;
     53
    3554  /* watch for response - wait up to 1 second */
    3655  line = NULL;
    3756  status = -1;
     57
     58  // how long does each cycle really take?
    3859  for (i = 0; (i < PCLIENT_TIMEOUT) && (status != 0) && (line == NULL); i++) {
    3960    status = ReadtoIOBuffer (buffer, host[0].stdout_fd);
     
    4566    return (PCLIENT_DOWN);
    4667  }
     68  if (line == NULL) return (PCLIENT_HUNG);
    4769  if (status == -1) return (PCLIENT_HUNG);
    48   /* gprint (GP_ERR, "buffer.buffer: %s\n", buffer[0].buffer); */
     70
     71  // fprintf (stderr, "response: %s\n", buffer[0].buffer);
     72
    4973  return (PCLIENT_GOOD);
    5074}
    5175
    5276/* memstr returns a view, not an allocated string : don't free */
     77/* ReadtoIOBuffer returns :
     78    0 - pipe closed
     79   -1 - no more data in pipe, data not ready
     80   -2 - serious error reading from pipe
     81   >0 - data read from pipe
     82*/
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/ResetJob.c

    r16472 r18424  
    11# include "pcontrol.h"
     2
     3// XXX deprecated
    24
    35int ResetJob (Job *job) {
    46 
    57  int       status;
    6   IOBuffer  buffer;
    78  Host     *host;
    89
     
    1314  ASSERT (job != NULL, "host missing");
    1415
    15   InitIOBuffer (&buffer, 0x100);
    16  
    1716  /* we have tried to reset the job; may not get status */
    1817  job[0].Reset = TRUE;
    1918
    20   status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);
     19  status = PclientCommand (host, "reset");
    2120
    2221  /* check on success of pclient command */
    2322  switch (status) {
    2423    case PCLIENT_DOWN:
    25       /*** different behavior for ANYHOST, WANTHOST, NEEDHOST? ***/
    26       gprint (GP_ERR, "host %s is down\n", host[0].hostname);
     24      if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    2725      HarvestHost (host[0].pid);
    2826      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    29       FreeIOBuffer (&buffer);
    30       return (FALSE);
    31 
    32     case PCLIENT_HUNG:
    33       /*** should we consider a HUNG host DOWN? ***/
    34       gprint (GP_ERR, "host %s is not responding (ResetJob)\n", host[0].hostname);
    35       FreeIOBuffer (&buffer);
    3627      return (FALSE);
    3728
    3829    case PCLIENT_GOOD:
    39       gprint (GP_ERR, "message received (ResetJob)\n"); 
    40       FreeIOBuffer (&buffer);
     30      host[0].response_state = PCONTROL_RESP_RESET_JOB;
     31      host[0].response = PCLIENT_PROMPT;
     32      FlushIOBuffer (&host[0].comms_buffer, 0x100);
     33      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
    4134      return (TRUE);
    4235
    4336    default:
    44       gprint (GP_ERR, "unknown status for pclient command: programming error\n"); 
    45       pcontrol_exit (55);
     37      ABORT ("unknown status for pclient command"); 
    4638  }
     39  ABORT ("should not reach here (ResetJob)");
     40}
    4741
    48   gprint (GP_ERR, "programming error in ResetJob (should not reach here)\n");
    49   FreeIOBuffer (&buffer);
    50   pcontrol_exit (56);
    51   return (FALSE);
     42int ResetJobResponse (Host *host) {
     43 
     44  int       status;
     45  IOBuffer *buffer;
     46
     47  /* job must have assigned host */
     48  ASSERT (host, "missing host");
     49  ASSERT (host[0].job, "missing job");
     50  buffer = host[0].comms_buffer;
     51
     52  gprint (GP_ERR, "message received (ResetJob)\n"); 
     53  return (TRUE);
    5254}
    5355
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/StartJob.c

    r11388 r18424  
    11# include "pcontrol.h"
    22
     3// job and host are bound together (why pass in both?)
    34int StartJob (Job *job, Host *host) {
    45
    56  int  i, Nline, status;
    6   char *line, *p;
    7   IOBuffer buffer;
    8 
    9   InitIOBuffer (&buffer, 0x100);
     7  char *line;
    108
    119  /* job must have assigned host */
     
    2826  }
    2927
    30   status = PclientCommand (host, line, PCLIENT_PROMPT, &buffer);
     28  status = PclientCommand (host, line, PCLIENT_PROMPT, PCONTROL_RESP_START_JOB);
    3129  free (line);
    3230
     
    3432  switch (status) {
    3533    case PCLIENT_DOWN:
     34      // unlink host & job
    3635      if (VerboseMode()) gprint (GP_ERR, "host %s is down\n", host[0].hostname);
    37       goto failure;
    38 
    39     case PCLIENT_HUNG:
    40       // we need the job start to return a valid Job ID,
    41       // give up on jobs which don't get started.
    42       // XXX we are sensitive here to the time it takes pclient
    43       // to fork the job.  if this is slow, the client may appear to hang.
    44       gprint (GP_ERR, "host %s is not responding (StartJob)\n", host[0].hostname);
    45       if (VerboseMode()) gprint (GP_ERR, "host %s is not responding\n", host[0].hostname);
    46 
    47       // unlink host & job
    4836      job[0].host = NULL;
    4937      host[0].job = NULL;
    50       if (job[0].realhost) free (job[0].realhost);
    51       job[0].realhost = NULL;
    52       PutHost (host, PCONTROL_HOST_DONE, STACK_BOTTOM);
     38      HarvestHost (host[0].pid);
     39      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    5340      PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
    54       FreeIOBuffer (&buffer);
    5541      return (FALSE);
    5642
    5743    case PCLIENT_GOOD:
    58       if (VerboseMode()) gprint (GP_ERR, "message received (StartJob)\n"); 
    59       break;
     44      job[0].realhost = strcreate (host[0].hostname);
     45      job[0].pid = -1;
     46      gettimeofday (&job[0].start, (void *) NULL);
     47
     48      if (VerboseMode()) gprint (GP_ERR, "started job on host %s\n", host[0].hostname); 
     49      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     50      PutJob (job, PCONTROL_JOB_RESP, STACK_BOTTOM);
     51      return (TRUE);
    6052
    6153    default:
    6254      ABORT ("unknown status for pclient command"); 
    6355  }
     56}
     57
     58// message has been received from the host, interpret results
     59int StartJobResponse (Host *host) {
     60 
     61  int status;
     62  char *p;
     63  IOBuffer *buffer;
     64  Job *job;
     65
     66  /* job must have assigned host */
     67  ASSERT (host, "missing host");
     68  ASSERT (host[0].job, "missing job");
     69  buffer = &host[0].comms_buffer;
     70  job = (Job *) host[0].job;
    6471
    6572  /* check on result of pclient command */
    66   p = memstr (buffer.buffer, "STATUS", buffer.Nbuffer);
    67   ASSERT (p != NULL, "missing STATUS in pclient message");
     73  p = memstr (buffer[0].buffer, "STATUS", buffer[0].Nbuffer);
     74  if (p == NULL) {
     75      // failed to get a valid response.  kill the job and try again,
     76      // or accept a running process without a PID?
     77      if (VerboseMode()) gprint (GP_ERR, "failed to get a valid PID, trying to continue without\n");
     78      PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
     79      PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
     80      gettimeofday (&job[0].start, NULL);
     81      return (TRUE);
     82  }
    6883
    6984  sscanf (p, "%*s %d", &status);
     
    7186    case -1:
    7287      if (VerboseMode()) gprint (GP_ERR, "error in pclient child\n");
    73       goto failure;
     88      // unlink host & job
     89      job[0].host = NULL;
     90      host[0].job = NULL;
     91      HarvestHost (host[0].pid);
     92      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
     93      PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
     94      return (FALSE);
    7495
    7596    case -2:
     
    80101
    81102    default:
    82       job[0].realhost = strcreate (host[0].hostname);
     103      if (VerboseMode()) gprint (GP_ERR, "message received (StartJobResponse)\n"); 
    83104      job[0].pid = status;
    84105      PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
    85106      PutJob (job, PCONTROL_JOB_BUSY, STACK_BOTTOM);
    86       FreeIOBuffer (&buffer);
    87       gettimeofday (&job[0].start, (void *) NULL);
     107      gettimeofday (&job[0].start, NULL);
    88108      return (TRUE);
    89109  }
     110
    90111  /* we should never reach here */
    91112  ABORT ("should not reach here (StartJob)");
    92 
    93 failure:
    94   // unlink host & job
    95   job[0].host = NULL;
    96   host[0].job = NULL;
    97   HarvestHost (host[0].pid);
    98   PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    99   PutJob (job, PCONTROL_JOB_PENDING, STACK_BOTTOM);
    100   FreeIOBuffer (&buffer);
    101   return (FALSE);
    102113}
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/StopHosts.c

    r16472 r18424  
    7272
    7373  int       status;
    74   IOBuffer  buffer;
    7574
    76   InitIOBuffer (&buffer, 0x100);
    77   status = PclientCommand (host, "exit", "Goodbye", &buffer);
    78   FreeIOBuffer (&buffer);
     75  status = PclientCommand (host, "exit", "Goodbye", PCONTROL_RESP_STOP_HOST);
    7976
    8077  /* check on success of pclient command */
    8178  switch (status) {
    8279    case PCLIENT_DOWN:
    83       break;
    84 
    85     case PCLIENT_HUNG:
    86       gprint (GP_ERR, "host %s is not responding\n", host[0].hostname);
     80      // XXX this is the desired result in any case, so ignore it
    8781      break;
    8882
    8983    case PCLIENT_GOOD:
    90       break;
     84      if (VerboseMode()) gprint (GP_ERR, "stop host %s\n", host[0].hostname); 
     85      FlushIOBuffer (&host[0].comms_buffer);
     86      PutHost (host, PCONTROL_HOST_RESP, STACK_BOTTOM);
     87      return (TRUE);
    9188
    9289    default:
    93       gprint (GP_ERR, "unknown status for pclient command: programming error\n"); 
    94       pcontrol_exit (57);
     90      ABORT ("unknown status for pclient command"); 
    9591  }
     92  ABORT ("should not reach here"); 
     93}
     94
     95int StopHostResponse (Host *host) {
     96
     97  OffHost (host);
    9698  HarvestHost (host[0].pid);
    9799  return (TRUE);
     
    103105  int i, result, waitstatus;
    104106
    105   gprint (GP_ERR, "harvesting within thread %d\n", pthread_self());
    106   gprint (GP_ERR, "child process %d is down, wait for exit status\n", pid);
     107  if (VerboseMode()) gprint (GP_ERR, "harvesting within thread %p\n", pthread_self());
     108  if (VerboseMode()) gprint (GP_ERR, "child process %d is down, wait for exit status\n", pid);
    107109 
    108110  // Loop a few times waiting for child to exit
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/check.c

    r11388 r18424  
    33int check (int argc, char **argv) {
    44
    5   Job *job;
    6   Host *host;
    7   int JobID, HostID, StackID;
     5  int JobID, HostID;
     6
     7  Stack *stack = NULL;
     8  Job *job = NULL;
     9  Host *host = NULL;
    810
    911  if (argc != 3) {
     
    1416
    1517  if (!strcasecmp (argv[1], "JOB")) {
    16     JobID = atoi (argv[2]);
     18    JobID = GetID (argv[2]);
     19    if (!JobID) {
     20      gprint (GP_ERR, "invalid job id %s\n", argv[2]);
     21      return (FALSE);
     22    }
    1723
    18     SetCheckPoint ();  // ensure the JOB is on one of the stacks
    19     job = PullJobByID (JobID, &StackID);
     24    stack = GetJobStack (PCONTROL_JOB_ALLJOBS);
     25    job = PullStackByID (stack, JobID);
    2026    if (job == NULL) {
    2127      gprint (GP_LOG, "job not found\n");
    22       ClearCheckPoint ();
    2328      return (FALSE);
    2429    }
    25     gprint (GP_LOG, "STATUS %s\n", GetJobStackName(StackID));
     30
     31    gprint (GP_LOG, "STATUS %s\n", GetJobStackName(job[0].stack));
    2632    gprint (GP_LOG, "EXITST %d\n", job[0].exit_status);
    2733    gprint (GP_LOG, "STDOUT %d\n", job[0].stdout_size);
     
    3339        gprint (GP_LOG, "HOSTNAME NONE\n");
    3440    }
    35     PutJob (job, StackID, STACK_BOTTOM);
    36     ClearCheckPoint ();
     41    PushStack (stack, STACK_BOTTOM, job, job[0].JobID, job[0].argv[0]);
    3742    return (TRUE);
    3843  }
     
    4146    HostID = atoi (argv[2]);
    4247
    43     SetCheckPoint ();  // ensure the HOST is on one of the stacks
    44     host = PullHostByID (HostID, &StackID);
     48    stack = GetHostStack (PCONTROL_HOST_ALLHOSTS);
     49    host = PullStackByID (stack, HostID);
    4550    if (host == NULL) {
    4651      gprint (GP_LOG, "host not found\n");
    47       ClearCheckPoint ();
    4852      return (FALSE);
    4953    }
    50     gprint (GP_LOG, "host %s\n", GetHostStackName(StackID));
    51     PutHost (host, StackID, STACK_BOTTOM);
    52     ClearCheckPoint ();
     54    gprint (GP_LOG, "host %s\n", GetHostStackName(host[0].stack));
     55    PushStack (stack, STACK_BOTTOM, host, host[0].HostID, host[0].hostname);
    5356    return (TRUE);
    5457  }
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/delete.c

    r8296 r18424  
    1010    return (FALSE);
    1111  }
    12   JobID = atoi (argv[1]);
     12  JobID = GetID (argv[1]);
     13  if (!JobID) {
     14    gprint (GP_ERR, "invalid job id %s\n", argv[1]);
     15    return (FALSE);
     16  }
     17     
    1318  /* use a string interp to convert JobIDs to ints ? */
    1419
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/host.c

    r10652 r18424  
    11# include "pcontrol.h"
    22
    3 // we use CheckPoints in this function to prevent objects in flight from being missing.
    43int host (int argc, char **argv) {
    54
    6   int StackID;
    75  IDtype HostID;
    86  Host *host;
     7  Stack *AllHosts;
    98
    109  if (argc != 3) goto usage;
     10
     11  AllHosts = GetHostStack (PCONTROL_HOST_ALLHOSTS);
    1112
    1213  if (!strcasecmp (argv[1], "ADD")) {
     
    1516    return (TRUE);
    1617  }
     18
     19  // this one is safe from in-flight entries: no one else pulls from OFF
    1720  if (!strcasecmp (argv[1], "ON")) {
    1821    host = PullHostFromStackByName (PCONTROL_HOST_OFF, argv[2]);
     
    2528    return (TRUE);
    2629  }
     30
     31  // this is a race condition with "CheckDownHosts", but the only
     32  // consequence is that both StartHost and reset set the times to 0.0
    2733  if (!strcasecmp (argv[1], "RETRY")) {
    2834    // no need to use a check point [thief: CheckDownHost (DOWN->IDLE)]
    29     host = PullHostFromStackByName (PCONTROL_HOST_DOWN, argv[2]);
     35    host = PullHostFromStackByName (PCONTROL_HOST_ALLHOSTS, argv[2]);
    3036    if (!host) {
     37      gprint (GP_LOG, "host %s not found\n", argv[2]);
     38      return (FALSE);
     39    }
     40    if (host[0].stack != PCONTROL_HOST_DOWN) {
    3141      gprint (GP_LOG, "host %s is not DOWN\n", argv[2]);
    3242      return (FALSE);
    3343    }
    34     /* reset time, place back on DOWN stack */
     44    /* reset time, place back on ALLHOSTS stack */
    3545    host[0].nexttry.tv_sec  = 0;
    3646    host[0].nexttry.tv_usec = 0;
    3747    host[0].lasttry.tv_sec  = 0;
    3848    host[0].lasttry.tv_usec = 0;
    39     PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
     49    PushStack (AllHosts, STACK_BOTTOM, host, host[0].HostID, host[0].hostname);
    4050    return (TRUE);
    4151  }
     52
    4253  if (!strcasecmp (argv[1], "CHECK")) {
    43     SetCheckPoint ();  // ensure the host is on one of the stacks
    44     host = PullHostByName (argv[2], &StackID);
     54    host = PullHostFromStackByName (PCONTROL_HOST_ALLHOSTS, argv[2]);
    4555    if (host == NULL) {
    4656      gprint (GP_LOG, "host %s not found\n", argv[2]);
    47       ClearCheckPoint ();
    4857      return (FALSE);
    4958    }
    50     PutHost (host, StackID, STACK_BOTTOM);
    51     ClearCheckPoint ();
    52 
    53     gprint (GP_LOG, "host %s is %s\n", argv[2], GetHostStackName (StackID));
     59    gprint (GP_LOG, "host %s is %s\n", argv[2], GetHostStackName (host[0].stack));
     60    PushStack (AllHosts, STACK_BOTTOM, host, host[0].HostID, host[0].hostname);
    5461    return (TRUE);
    5562  }
     63
    5664  if (!strcasecmp (argv[1], "OFF")) {
    57     SetCheckPoint (); // ensure we can find the specified host
    58     host = PullHostByName (argv[2], &StackID);
     65    host = PullHostFromStackByName (PCONTROL_HOST_ALLHOSTS, argv[2]);
    5966    if (host == NULL) {
    6067      gprint (GP_LOG, "host %s not found\n", argv[2]);
    61       ClearCheckPoint ();
    6268      return (FALSE);
    6369    }
    6470    host[0].markoff = TRUE;
    65     PutHost (host, StackID, STACK_BOTTOM);
    66     ClearCheckPoint ();
     71    PushStack (AllHosts, STACK_BOTTOM, host, host[0].HostID, host[0].hostname);
    6772    return (TRUE);
    6873  }
    6974
     75  // this one is safe from in-flight entries: no one else pulls from OFF
    7076  if (!strcasecmp (argv[1], "DELETE")) {
    71     // a check point is not required: no possible thief
    7277    host = PullHostFromStackByName (PCONTROL_HOST_OFF, argv[2]);
    7378    if (!host) {
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/pcontrol.c.in

    r16473 r18424  
    6868/* add program-dependent exit functions here */
    6969void cleanup () {
     70  // stop checking on the jobs
     71  SetRunLevel (PCONTROL_RUN_HOSTS);
    7072  DownHosts ();
    7173  ConfigFree ();
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/rconnect.c

    r16472 r18424  
    22
    33/* connection can take a while, allow up to 2 sec */
    4 # define CONNECT_TIMEOUT 500
     4# define CONNECT_TIMEOUT 5000
    55
    66/* connect to host, start the shell: ssh hostname pclient -> command hostname shell
     
    106106
    107107connect_error:
    108   if (VerboseMode()) gprint (GP_ERR, "error while connecting\n");
     108  if (VerboseMode()) gprint (GP_ERR, "error while connecting, status: %d, ncycles: %d\n", status, i);
    109109
    110110  /* avoid blocking on waitpid, test every 100 usec, up to 50 msec */
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/status.c

    r12471 r18424  
    66int status (int argc, char **argv) {
    77
    8   SetCheckPoint ();
    9   PrintJobStack (PCONTROL_JOB_PENDING);
    10   PrintJobStack (PCONTROL_JOB_BUSY);
    11   PrintJobStack (PCONTROL_JOB_DONE);
    12   PrintJobStack (PCONTROL_JOB_KILL);
    13   PrintJobStack (PCONTROL_JOB_EXIT);
    14   PrintJobStack (PCONTROL_JOB_CRASH);
     8  PrintJobStack (PCONTROL_JOB_ALLJOBS);
     9  PrintHostStack (PCONTROL_HOST_ALLHOSTS);
    1510
    16   PrintHostStack (PCONTROL_HOST_OFF);
    17   PrintHostStack (PCONTROL_HOST_DOWN);
    18   PrintHostStack (PCONTROL_HOST_IDLE);
    19   PrintHostStack (PCONTROL_HOST_BUSY);
    20   PrintHostStack (PCONTROL_HOST_DONE);
    21   ClearCheckPoint ();
    2211  return (TRUE);
    2312}
     
    3928    job = stack[0].object[i];
    4029    ASSERT (job != NULL, "programming error");
    41     gprint (GP_LOG, "%d  %s  %d  ", i, job[0].hostname, job[0].argc);
     30    if (job[0].realhost == NULL) {
     31        gprint (GP_LOG, "%3d %9s ", i, job[0].hostname);
     32    } else {
     33        gprint (GP_LOG, "%3d %9s ", i, job[0].realhost);
     34    }
     35    gprint (GP_LOG, "%7s  ", GetJobStackName (job[0].state));
    4236    for (j = 0; j < job[0].argc; j++) {
    4337      gprint (GP_LOG, "%s ", job[0].argv[j]);
     
    6660    host = stack[0].object[i];
    6761    gprint (GP_LOG, "%d  %s  ", i, host[0].hostname);
     62    gprint (GP_LOG, "%5s  ", GetHostStackName (host[0].stack));
    6863    PrintID (GP_LOG, host[0].HostID);
    6964    gprint (GP_LOG, "\n");
  • branches/eam_branch_20080421/Ohana/src/opihi/pcontrol/stdout.c

    r12840 r18424  
    11# include "pcontrol.h"
    22
     3// XXX unify by testing for value of argv[0]
    34int stdout_pc (int argc, char **argv) {
    45
    5   int JobID, StackID;
     6  int N, JobID, StackID;
    67  Job *job;
    78  IOBuffer *buffer;
     9  char *varName;
     10
     11  varName = NULL;
     12  if ((N = get_argument (argc, argv, "-var"))) {
     13    remove_argument (N, &argc, argv);
     14    varName = strcreate (argv[N]);
     15    remove_argument (N, &argc, argv);
     16  }
    817
    918  if (argc != 2) {
    10     gprint (GP_ERR, "USAGE: stdout (JobID)\n");
     19    gprint (GP_ERR, "USAGE: stdout (JobID) [-var name]\n");
    1120    gprint (GP_LOG, "STATUS %d\n", -1);
    1221    return (FALSE);
     
    2534
    2635  gprint (GP_ERR, "job not found in EXIT or CRASH\n");
    27   gprint (GP_LOG, "STATUS %d\n", -2);
     36  if (varName == NULL) {
     37    gprint (GP_LOG, "STATUS %d\n", -2);
     38  } else {
     39    set_str_variable (varName, "NULL");
     40    free (varName);
     41  }
    2842  return (FALSE);
    2943
    3044found_stdout:
    3145  buffer = &job[0].stdout_buff;
    32   fwrite (buffer[0].buffer, 1, buffer[0].Nbuffer, stdout);
    33   gprint (GP_LOG, "STATUS %d\n", 0);
     46  if (varName == NULL) {
     47    fwrite (buffer[0].buffer, 1, buffer[0].Nbuffer, stdout);
     48    gprint (GP_LOG, "STATUS %d\n", 0);
     49  } else {
     50    // XXX this can drop '0' values
     51    set_str_variable (varName, buffer[0].buffer);
     52    free (varName);
     53  }
    3454  PutJob (job, StackID, STACK_BOTTOM);
    3555  return (TRUE);
     
    3858int stderr_pc (int argc, char **argv) {
    3959
    40   int JobID, StackID;
     60  int N, JobID, StackID;
    4161  Job *job;
    4262  IOBuffer *buffer;
     63  char *varName;
     64
     65  varName = NULL;
     66  if ((N = get_argument (argc, argv, "-var"))) {
     67    remove_argument (N, &argc, argv);
     68    varName = strcreate (argv[N]);
     69    remove_argument (N, &argc, argv);
     70  }
    4371
    4472  if (argc != 2) {
    45     gprint (GP_ERR, "USAGE: stderr (JobID)\n");
     73    gprint (GP_ERR, "USAGE: stderr (JobID) [-var name]\n");
    4674    gprint (GP_LOG, "STATUS %d\n", -1);
    4775    return (FALSE);
     
    6088
    6189  gprint (GP_ERR, "job not found in EXIT or CRASH\n");
    62   gprint (GP_LOG, "STATUS %d\n", -2);
     90  if (varName == NULL) {
     91    gprint (GP_LOG, "STATUS %d\n", -2);
     92  } else {
     93    set_str_variable (varName, "NULL");
     94    free (varName);
     95  }
    6396  return (FALSE);
    6497
    6598found_stderr:
    6699  buffer = &job[0].stderr_buff;
    67   fwrite (buffer[0].buffer, 1, buffer[0].Nbuffer, stdout);
    68   gprint (GP_LOG, "STATUS %d\n", 0);
     100  if (varName == NULL) {
     101    fwrite (buffer[0].buffer, 1, buffer[0].Nbuffer, stdout);
     102    gprint (GP_LOG, "STATUS %d\n", 0);
     103  } else {
     104    // XXX this can drop '0' values
     105    set_str_variable (varName, buffer[0].buffer);
     106    free (varName);
     107  }
    69108  PutJob (job, StackID, STACK_BOTTOM);
    70109  return (TRUE);
Note: See TracChangeset for help on using the changeset viewer.