mirror of
https://github.com/eddyem/SBIG_340.git
synced 2025-12-06 10:45:10 +03:00
Add timestamps to saved filenames, fix daemon()
This commit is contained in:
parent
f6f0bd6f0f
commit
d123815433
40
Makefile
40
Makefile
@ -2,16 +2,18 @@
|
|||||||
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
|
LDFLAGS := -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,--discard-all
|
||||||
LDFLAGS += -lm -pthread
|
LDFLAGS += -lm -pthread
|
||||||
SRCS := $(wildcard *.c)
|
SRCS := $(wildcard *.c)
|
||||||
DEFINES := $(DEF) -D_XOPEN_SOURCE=1111
|
#GCC_GE_4_9_3 := $(shell g++ -dumpversion | gawk '{print $$1>=4.9.3?"1":"0"}')
|
||||||
DEFINES += -DEBUG
|
DEFINES := $(DEF) -D_XOPEN_SOURCE=1111
|
||||||
#OBJDIR := mk
|
#ifeq ($(GCC_GE_4_9_3),1)
|
||||||
CFLAGS += -O2 -Wall -Werror -Wextra -Wno-trampolines -std=gnu99
|
DEFINES += -D_DEFAULT_SOURCE
|
||||||
#OBJS := $(addprefix $(OBJDIR)/, $(SRCS:%.c=%.o))
|
#else
|
||||||
#DEPS := $(OBJS:.o=.d)
|
# DEFINES += -D_BSD_SOURCE
|
||||||
|
#endif
|
||||||
|
#DEFINES += -DEBUG
|
||||||
|
CFLAGS += -Wall -Wextra -O2 -std=gnu99
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|
||||||
all : sbig340 daemon client
|
all : sbig340 daemon client
|
||||||
# $(OBJDIR)
|
|
||||||
|
|
||||||
sbig340 : $(SRCS)
|
sbig340 : $(SRCS)
|
||||||
@echo -e "\t\tLD sbig340"
|
@echo -e "\t\tLD sbig340"
|
||||||
@ -25,27 +27,11 @@ client : $(SRCS)
|
|||||||
@echo -e "\t\tLD client"
|
@echo -e "\t\tLD client"
|
||||||
$(CC) -DCLIENT $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o client
|
$(CC) -DCLIENT $(CFLAGS) $(DEFINES) $(LDFLAGS) $(shell pkg-config --libs cfitsio) -ltiff $(SRCS) -o client
|
||||||
|
|
||||||
#$(OBJDIR):
|
clean:
|
||||||
# mkdir $(OBJDIR)
|
@echo -e "\t\tCLEAN"
|
||||||
|
@rm -f sbig340 daemon client
|
||||||
#ifneq ($(MAKECMDGOALS),clean)
|
|
||||||
#-include $(DEPS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#$(OBJDIR)/%.o: %.c
|
|
||||||
# @echo -e "\t\tCC $<"
|
|
||||||
# $(CC) -MD -c $(LDFLAGS) $(CFLAGS) $(DEFINES) -o $@ $<
|
|
||||||
|
|
||||||
#clean:
|
|
||||||
# @echo -e "\t\tCLEAN"
|
|
||||||
# @rm -f $(OBJS) $(DEPS)
|
|
||||||
# @rmdir $(OBJDIR) 2>/dev/null || true
|
|
||||||
|
|
||||||
#xclean: clean
|
|
||||||
# @rm -f $(PROGRAM)
|
|
||||||
|
|
||||||
gentags:
|
gentags:
|
||||||
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null
|
CFLAGS="$(CFLAGS) $(DEFINES)" geany -g $(PROGRAM).c.tags *[hc] 2>/dev/null
|
||||||
|
|
||||||
.PHONY: gentags
|
.PHONY: gentags clean
|
||||||
#clean xclean
|
|
||||||
|
|||||||
@ -53,8 +53,10 @@ glob_pars const Gdefault = {
|
|||||||
.imformat = NULL,
|
.imformat = NULL,
|
||||||
.imstoretype = NULL,
|
.imstoretype = NULL,
|
||||||
.outpfname = "output.tiff",
|
.outpfname = "output.tiff",
|
||||||
.hostname = "localhost",
|
.hostname = NULL,
|
||||||
.port = "4444"
|
.port = "4444",
|
||||||
|
.once = 0,
|
||||||
|
.timestamp = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -93,6 +95,8 @@ myoption cmdlnopts[] = {
|
|||||||
#if defined DAEMON || defined CLIENT
|
#if defined DAEMON || defined CLIENT
|
||||||
#ifndef DAEMON
|
#ifndef DAEMON
|
||||||
{"hostname",NEED_ARG, NULL, 'H', arg_string, APTR(&G.hostname), _("hostname to connect (default: localhost)")},
|
{"hostname",NEED_ARG, NULL, 'H', arg_string, APTR(&G.hostname), _("hostname to connect (default: localhost)")},
|
||||||
|
{"once", NO_ARGS, NULL, '1', arg_int, APTR(&G.once), _("run client just once")},
|
||||||
|
{"timestamp",NO_ARGS, NULL, 't', arg_int, APTR(&G.timestamp), _("add timestamp to filename")},
|
||||||
#endif
|
#endif
|
||||||
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: 4444)")},
|
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("port to connect (default: 4444)")},
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -35,6 +35,8 @@ typedef struct{
|
|||||||
int rest_pars_num; // number of rest parameters
|
int rest_pars_num; // number of rest parameters
|
||||||
heater_cmd heater; // turn heater on/off/leave unchanged
|
heater_cmd heater; // turn heater on/off/leave unchanged
|
||||||
int splist; // list speeds available
|
int splist; // list speeds available
|
||||||
|
int once; // run once (client)
|
||||||
|
int timestamp; // add timestamp
|
||||||
int newspeed; // change speed
|
int newspeed; // change speed
|
||||||
int speed; // connect @ this speed
|
int speed; // connect @ this speed
|
||||||
char *shutter_cmd; // shutter command: 'o' for open, 'c' for close, 'k' for de-energize
|
char *shutter_cmd; // shutter command: 'o' for open, 'c' for close, 'k' for de-energize
|
||||||
|
|||||||
@ -25,10 +25,12 @@
|
|||||||
#include "imfunctions.h"
|
#include "imfunctions.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include <strings.h> // strncasecmp
|
#include <strings.h> // strncasecmp
|
||||||
#include <tiffio.h> // save tiff
|
|
||||||
#include <math.h> // sqrt
|
#include <math.h> // sqrt
|
||||||
#include <time.h> // time, gmtime etc
|
#include <time.h> // time, gmtime etc
|
||||||
|
#ifndef DAEMON
|
||||||
#include <fitsio.h> // save fits
|
#include <fitsio.h> // save fits
|
||||||
|
#include <tiffio.h> // save tiff
|
||||||
|
#endif
|
||||||
#include <libgen.h> // basename
|
#include <libgen.h> // basename
|
||||||
#include <sys/stat.h> // utimensat
|
#include <sys/stat.h> // utimensat
|
||||||
#include <fcntl.h> // AT_...
|
#include <fcntl.h> // AT_...
|
||||||
@ -38,7 +40,8 @@ double exp_calculated = -1.; // optimal exposition, calculated in histogram save
|
|||||||
* All image-storing functions modify ctime of saved files to be the time of
|
* All image-storing functions modify ctime of saved files to be the time of
|
||||||
* exposition start!
|
* exposition start!
|
||||||
*/
|
*/
|
||||||
|
#ifndef DAEMON
|
||||||
|
#include <time.h>
|
||||||
void modifytimestamp(char *filename, imstorage *img){
|
void modifytimestamp(char *filename, imstorage *img){
|
||||||
if(!filename) return;
|
if(!filename) return;
|
||||||
struct timespec times[2];
|
struct timespec times[2];
|
||||||
@ -58,9 +61,19 @@ void modifytimestamp(char *filename, imstorage *img){
|
|||||||
* make filename for given name, suffix and storage type
|
* make filename for given name, suffix and storage type
|
||||||
* @return filename or NULL if can't create it
|
* @return filename or NULL if can't create it
|
||||||
*/
|
*/
|
||||||
static char *make_filename(const char *outfile, const char *suff, store_type st){
|
static char *make_filename(imstorage *img, const char *suff){
|
||||||
struct stat filestat;
|
struct stat filestat;
|
||||||
static char buff[FILENAME_MAX];
|
static char buff[FILENAME_MAX];
|
||||||
|
store_type st = img->st;
|
||||||
|
char fnbuf[FILENAME_MAX], *outfile = img->imname;
|
||||||
|
if(img->timestamp){
|
||||||
|
struct tm *stm = localtime(&img->exposetime);
|
||||||
|
// add timestamp as YYYY-MM-DD_hh:mm:ss
|
||||||
|
snprintf(fnbuf, FILENAME_MAX, "%s_%04d-%02d-%02d_%02d:%02d:%02d", outfile,
|
||||||
|
1900+stm->tm_year, 1+stm->tm_mon, stm->tm_mday,
|
||||||
|
stm->tm_hour, stm->tm_min, stm->tm_sec);
|
||||||
|
outfile = fnbuf;
|
||||||
|
}
|
||||||
if(st == STORE_NORMAL || st == STORE_REWRITE){
|
if(st == STORE_NORMAL || st == STORE_REWRITE){
|
||||||
snprintf(buff, FILENAME_MAX, "%s.%s", outfile, suff);
|
snprintf(buff, FILENAME_MAX, "%s.%s", outfile, suff);
|
||||||
if(stat(buff, &filestat)){
|
if(stat(buff, &filestat)){
|
||||||
@ -143,18 +156,20 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
|
|||||||
#define FMTSZ (3)
|
#define FMTSZ (3)
|
||||||
image_format formats[FMTSZ] = {FORMAT_FITS, FORMAT_TIFF, FORMAT_RAW};
|
image_format formats[FMTSZ] = {FORMAT_FITS, FORMAT_TIFF, FORMAT_RAW};
|
||||||
const char *suffixes[FMTSZ] = {SUFFIX_FITS, SUFFIX_TIFF, SUFFIX_RAW};
|
const char *suffixes[FMTSZ] = {SUFFIX_FITS, SUFFIX_TIFF, SUFFIX_RAW};
|
||||||
for(size_t i = 0; i < FMTSZ; ++i){
|
|
||||||
if(!(formats[i] & fmt)) continue;
|
|
||||||
if(!make_filename(nm, suffixes[i], st)){
|
|
||||||
WARNX(_("Can't create output file (is it exists?)"));
|
|
||||||
free(nm);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
imstorage *ist = MALLOC(imstorage, 1);
|
imstorage *ist = MALLOC(imstorage, 1);
|
||||||
ist->st = st;
|
ist->st = st;
|
||||||
ist->imformat = fmt;
|
ist->imformat = fmt;
|
||||||
ist->imname = strdup(nm);
|
ist->imname = strdup(nm);
|
||||||
|
for(size_t i = 0; i < FMTSZ; ++i){
|
||||||
|
if(!(formats[i] & fmt)) continue;
|
||||||
|
if(!make_filename(ist, suffixes[i])){
|
||||||
|
WARNX(_("Can't create output file (is it exists?)"));
|
||||||
|
free(nm);
|
||||||
|
free(ist->imname);
|
||||||
|
free(ist);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ist;
|
return ist;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +180,7 @@ imstorage *chk_storeimg(char *filename, char* store, char *format){
|
|||||||
int writetiff(imstorage *img){
|
int writetiff(imstorage *img){
|
||||||
int H = img->H, W = img->W, y;
|
int H = img->H, W = img->W, y;
|
||||||
uint16_t *data = img->imdata;
|
uint16_t *data = img->imdata;
|
||||||
char *name = make_filename(img->imname, SUFFIX_TIFF, img->st);
|
char *name = make_filename(img, SUFFIX_TIFF);
|
||||||
TIFF *image = NULL;
|
TIFF *image = NULL;
|
||||||
if(!name || !(image = TIFFOpen(name, "w"))){
|
if(!name || !(image = TIFFOpen(name, "w"))){
|
||||||
WARN("Can't save tiff file");
|
WARN("Can't save tiff file");
|
||||||
@ -195,6 +210,7 @@ int writetiff(imstorage *img){
|
|||||||
modifytimestamp(name, img);
|
modifytimestamp(name, img);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate image statistics: print it on screen and save for `writefits`
|
* Calculate image statistics: print it on screen and save for `writefits`
|
||||||
@ -243,6 +259,7 @@ void print_stat(imstorage *img){
|
|||||||
printf("At 3sigma: Noverload = %ld, avr = %.3f, std = %.3f\n", Noverld, avr, std);
|
printf("At 3sigma: Noverload = %ld, avr = %.3f, std = %.3f\n", Noverld, avr, std);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DAEMON
|
||||||
#define TRYFITS(f, ...) \
|
#define TRYFITS(f, ...) \
|
||||||
do{ int status = 0; \
|
do{ int status = 0; \
|
||||||
f(__VA_ARGS__, &status); \
|
f(__VA_ARGS__, &status); \
|
||||||
@ -260,7 +277,7 @@ int writefits(imstorage *img){
|
|||||||
long naxes[2] = {img->W, img->H};
|
long naxes[2] = {img->W, img->H};
|
||||||
char buf[80];
|
char buf[80];
|
||||||
fitsfile *fp;
|
fitsfile *fp;
|
||||||
char *filename = make_filename(img->imname, SUFFIX_FITS, img->st);
|
char *filename = make_filename(img, SUFFIX_FITS);
|
||||||
TRYFITS(fits_create_file, &fp, filename);
|
TRYFITS(fits_create_file, &fp, filename);
|
||||||
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
TRYFITS(fits_create_img, fp, USHORT_IMG, 2, naxes);
|
||||||
// FILE / Input file original name
|
// FILE / Input file original name
|
||||||
@ -293,9 +310,9 @@ int writefits(imstorage *img){
|
|||||||
WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type");
|
WRITEKEY(TSTRING, "IMAGETYP", buf, "Image type");
|
||||||
// DATAMAX, DATAMIN / Max,min pixel value
|
// DATAMAX, DATAMIN / Max,min pixel value
|
||||||
uint16_t val = UINT16_MAX;
|
uint16_t val = UINT16_MAX;
|
||||||
WRITEKEY(TUSHORT, "DATAMAX", &val, "Max pixel value");
|
WRITEKEY(TUSHORT, "DATAMAX", &val, "Max possible pixel value");
|
||||||
val = 0;
|
val = 0;
|
||||||
WRITEKEY(TUSHORT, "DATAMIN", &val, "Min pixel value");
|
WRITEKEY(TUSHORT, "DATAMIN", &val, "Min possible pixel value");
|
||||||
// statistical values
|
// statistical values
|
||||||
WRITEKEY(TUSHORT, "STATMAX", &glob_max, "Max pixel value");
|
WRITEKEY(TUSHORT, "STATMAX", &glob_max, "Max pixel value");
|
||||||
WRITEKEY(TUSHORT, "STATMIN", &glob_min, "Min pixel value");
|
WRITEKEY(TUSHORT, "STATMIN", &glob_min, "Min pixel value");
|
||||||
@ -335,6 +352,7 @@ int writefits(imstorage *img){
|
|||||||
green(_("Image %s saved\n"), filename);
|
green(_("Image %s saved\n"), filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CLIENT
|
#ifndef CLIENT
|
||||||
/**
|
/**
|
||||||
@ -406,8 +424,9 @@ int save_histo(FILE *f, imstorage *img){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DAEMON
|
||||||
int writedump(imstorage *img){
|
int writedump(imstorage *img){
|
||||||
char *name = make_filename(img->imname, SUFFIX_RAW, img->st);
|
char *name = make_filename(img, SUFFIX_RAW);
|
||||||
if(!name) return 1;
|
if(!name) return 1;
|
||||||
int f = open(name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
int f = open(name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
if(f){
|
if(f){
|
||||||
@ -423,7 +442,7 @@ int writedump(imstorage *img){
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
modifytimestamp(name, img);
|
modifytimestamp(name, img);
|
||||||
name = make_filename(img->imname, "histogram.txt", img->st);
|
name = make_filename(img, "histogram.txt");
|
||||||
if(!name) return 4;
|
if(!name) return 4;
|
||||||
FILE *h = fopen(name, "w");
|
FILE *h = fopen(name, "w");
|
||||||
if(!h) return 5;
|
if(!h) return 5;
|
||||||
@ -466,3 +485,4 @@ int store_image(imstorage *img){
|
|||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@ -66,6 +66,8 @@ typedef struct{
|
|||||||
size_t W, H; // image size
|
size_t W, H; // image size
|
||||||
uint16_t *imdata; // image data itself
|
uint16_t *imdata; // image data itself
|
||||||
time_t exposetime; // time of exposition start
|
time_t exposetime; // time of exposition start
|
||||||
|
int timestamp; // add timestamp to filename
|
||||||
|
int once; // get only one image
|
||||||
} imstorage;
|
} imstorage;
|
||||||
|
|
||||||
extern double exp_calculated;
|
extern double exp_calculated;
|
||||||
|
|||||||
4
main.c
4
main.c
@ -111,6 +111,10 @@ int main(int argc, char **argv){
|
|||||||
run_terminal(); // non-echo terminal mode
|
run_terminal(); // non-echo terminal mode
|
||||||
}
|
}
|
||||||
#endif // !defined DAEMON && !defined CLIENT
|
#endif // !defined DAEMON && !defined CLIENT
|
||||||
|
#ifdef CLIENT
|
||||||
|
img->once = G->once;
|
||||||
|
img->timestamp = G->timestamp;
|
||||||
|
#endif
|
||||||
#if defined CLIENT || defined DAEMON
|
#if defined CLIENT || defined DAEMON
|
||||||
daemonize(img, G->hostname, G->port);
|
daemonize(img, G->hostname, G->port);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
9
socket.c
9
socket.c
@ -31,6 +31,9 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <limits.h> // INT_xxx
|
#include <limits.h> // INT_xxx
|
||||||
#include <signal.h> // pthread_kill
|
#include <signal.h> // pthread_kill
|
||||||
|
#include <unistd.h> // daemon
|
||||||
|
#include <sys/wait.h> // wait
|
||||||
|
#include <sys/prctl.h> //prctl
|
||||||
|
|
||||||
#define BUFLEN (10240)
|
#define BUFLEN (10240)
|
||||||
#define BUFLEN10 (1048576)
|
#define BUFLEN10 (1048576)
|
||||||
@ -396,6 +399,7 @@ static void client_(imstorage *img, int sock){
|
|||||||
if(store_image(img))
|
if(store_image(img))
|
||||||
WARNX(_("Error storing image"));
|
WARNX(_("Error storing image"));
|
||||||
}
|
}
|
||||||
|
if(img->once) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -405,8 +409,9 @@ static void client_(imstorage *img, int sock){
|
|||||||
*/
|
*/
|
||||||
void daemonize(imstorage *img, char *hostname, char *port){
|
void daemonize(imstorage *img, char *hostname, char *port){
|
||||||
FNAME();
|
FNAME();
|
||||||
green("Daemonize\n");
|
|
||||||
#ifndef EBUG
|
#ifndef EBUG
|
||||||
|
if(!img->once){
|
||||||
|
green("Daemonize\n");
|
||||||
if(daemon(1, 0)){
|
if(daemon(1, 0)){
|
||||||
ERR("daemon()");
|
ERR("daemon()");
|
||||||
}
|
}
|
||||||
@ -421,7 +426,7 @@ void daemonize(imstorage *img, char *hostname, char *port){
|
|||||||
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
prctl(PR_SET_PDEATHSIG, SIGTERM); // send SIGTERM to child when parent dies
|
||||||
break; // go out to normal functional
|
break; // go out to normal functional
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
#endif
|
#endif
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
struct addrinfo hints, *res, *p;
|
struct addrinfo hints, *res, *p;
|
||||||
|
|||||||
2
term.h
2
term.h
@ -41,7 +41,7 @@ typedef enum{
|
|||||||
} heater_cmd;
|
} heater_cmd;
|
||||||
|
|
||||||
// terminal timeout (seconds)
|
// terminal timeout (seconds)
|
||||||
#define WAIT_TMOUT (0.1)
|
#define WAIT_TMOUT (0.2)
|
||||||
// timeout waitint 'D'
|
// timeout waitint 'D'
|
||||||
#define EXP_DONE_TMOUT (5.0)
|
#define EXP_DONE_TMOUT (5.0)
|
||||||
// dataportion transfer timeout
|
// dataportion transfer timeout
|
||||||
|
|||||||
@ -333,7 +333,7 @@ size_t read_tty(uint8_t *buff, size_t length){
|
|||||||
int retval;
|
int retval;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(comfd, &rfds);
|
FD_SET(comfd, &rfds);
|
||||||
tv.tv_sec = 0; tv.tv_usec = 50000; // wait for 50ms
|
tv.tv_sec = 0; tv.tv_usec = 500000; // wait for 500ms max
|
||||||
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
retval = select(comfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
if (!retval) return 0;
|
if (!retval) return 0;
|
||||||
if(FD_ISSET(comfd, &rfds)){
|
if(FD_ISSET(comfd, &rfds)){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user