示例#1
0
/* Receive a byte through the virtual link
* On error: Throws a Byte Exception */
static u_char link_recv(CPU_t *cpu) {
	link_t *link = cpu->pio.link;
	u_char byte = 0;
	u_int i;

	for (u_int bit = 0; bit < 8; bit++) {
		byte >>= 1;

		for (i = 0; i < LINK_TIMEOUT && vlink(link) == 3; i += LINK_STEP)
			link_wait(cpu, LINK_STEP);

		if (vlink(link) == 0)
			longjmp(exc_byte, LERR_LINK);
		if (i >= LINK_TIMEOUT)
			longjmp(exc_byte, LERR_TIMEOUT);

		link->vout = vlink(link);
		if (link->vout == 1)
			byte |= 0x80;

		for (i = 0; i < LINK_TIMEOUT && vlink(link) == 0; i += LINK_STEP)
			link_wait(cpu, LINK_STEP);
		if (i >= LINK_TIMEOUT)
			longjmp(exc_byte, LERR_TIMEOUT);
		link->vout = 0;
	}

	cpu->pio.link->vlink_recv++;
	return byte;
}
示例#2
0
/* Send a byte through the virtual link
 * On error: Throws a Byte Exception */
static void link_send(CPU_t *cpu, u_char byte) {
	link_t *link = cpu->pio.link;
	u_int i;

	for (u_int bit = 0; bit < 8; bit++, byte >>= 1) {
		link->vout = (byte & 1) + 1;

		for (i = 0; i < LINK_TIMEOUT && vlink(link) != 0; i += LINK_STEP)
			link_wait(cpu, LINK_STEP);
		if (i >= LINK_TIMEOUT)
			longjmp(exc_byte, LERR_TIMEOUT);

		link->vout = 0;
		for (i = 0; i < LINK_TIMEOUT && vlink(link) != 3; i += LINK_STEP)
			link_wait(cpu, LINK_STEP);
		if (i >= LINK_TIMEOUT)
			longjmp(exc_byte, LERR_TIMEOUT);
	}

	cpu->pio.link->vlink_send++;
}
示例#3
0
/* Send a TI packet over the virtual link
 * On error: Throws a Packet Exception */
void link_send_pkt(CPU_t *cpu, u_char command_ID, void *data) {
	TI_PKTHDR hdr;
	uint16_t data_len;

	hdr.machine_ID = link_target_ID(cpu);
	hdr.command_ID = command_ID;
#ifdef _DEBUG
	printf("SEND: ");
	print_command_ID(command_ID);
	putchar(' ');
#endif
	switch (command_ID) {
	case CID_VAR:
	case CID_DEL:
	case CID_REQ:
	case CID_RTS: {
		uint8_t type_ID = ((TI_VARHDR *) data)->type_ID;

		if (type_ID == BackupObj || (type_ID == BackupObj_82 && cpu->pio.model == TI_82))
			data_len = sizeof(TI_BACKUPHDR);
		else if (type_ID >= 0x22 && type_ID <= 0x28)
			data_len = sizeof(TI_FLASHHDR);
		else {
			data_len = sizeof(TI_VARHDR);
			// Non flash calculators do not pass
			// version or 2nd flags
			if (cpu->pio.model < TI_83P) {
				//85/86 does have name length 
				if (cpu->pio.model == TI_85 || cpu->pio.model == TI_86) {
					data_len--;
				} else {
					data_len -= 2;
				}
			}
		}
		cpu->pio.link->vlink_send -= (sizeof(TI_PKTHDR) + data_len);
		break;
	}
	case CID_DATA:
		data_len = ((TI_DATA*) data)->length;
		data = ((TI_DATA*) data)->data;
		cpu->pio.link->vlink_send -= (sizeof(TI_PKTHDR));
		break;
	case CID_EXIT:
		data_len = 5;
		cpu->pio.link->vlink_send -= (sizeof(TI_PKTHDR) + data_len);
		break;
	default:
		data_len = 0;
		cpu->pio.link->vlink_send -= (sizeof(TI_PKTHDR) + data_len);
		break;
	}

#ifdef _DEBUG
	printf("(%d) ", data_len);
	if (command_ID != CID_DATA) {
		int i;
		for (i = 0; i < data_len; i++) {
			printf("%02x ", ((u_char *) data)[i]);
		}
	}
	putchar('\n');
#endif

	int err;
	switch (err = setjmp(exc_byte)) {
	case 0:
		link_wait(cpu, LINK_DELAY);
		//if (command_ID == CID_DATA)
		//	data_len--;
		hdr.data_len = link_endian(data_len);
		link_send_bytes(cpu, &hdr, sizeof(TI_PKTHDR));
		if (data_len != 0) {
			uint16_t chksum = link_endian(link_chksum(data, data_len));
			link_send_bytes(cpu, data, data_len);
			link_send_bytes(cpu, &chksum, sizeof(chksum));
			cpu->pio.link->vlink_send -= sizeof(chksum);
		}
		return;
	default:
		return longjmp(exc_pkt, err);
	}
}
示例#4
0
文件: core.c 项目: mikekmv/rubsd
int main(int argc, char ** argv)
{  int             c;
   int             fd;
   int             rc;
   int             i;
   int             fRun     = 0;
   int             fDaemon  = 0;
   int             fUpdate  = 0;
   int             fConvert = 0;
   int             fSQL     = 0;
   int             fDumpGates = 0;

   accbase_t       Accbase_temp;
   acc_t           new_acc;
   acc_t_old       old_acc; 

   char         ** row;

   res_coreinit();

   openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);

//   DumpQuery = 1;

/*
 A  1. Redefine service port
 u  2. Update access at start
 d  3. Run Daemon
 c  4. Run console
*/

   while ((c = getopt(argc, argv, OPTS)) != -1)
   {  switch (c)
      {
         case 'A':
            ForceService = strtol(optarg, NULL, 10);
            break;

         case '2':
            fSQL = 1;
            break;

         case 'v':   // verbose - show queries
            DumpQuery = 1;
            break;


         case 'f':
            Config_path = optarg;
            break;

         case 'c':
            ld->fStdio = 1;
            fRun       = 1;
            break;

         case 'd':
            fDaemon = 1;
            fRun    = 1;
            break;

         case 'u':
            fUpdate = 1;
            break;

         case 'o':
            fConvert = 1;
            break;

         case 't':
            proc_title = optarg;
            break;

         case 'Q':
            QueryFilename = optarg;
            break;

         case 'g':
            fDumpGates = 1;
            break;

         case 'q':
            QuietMode = 1;
            break;

         case 'h':
         case '?':
	    usage(0);

         default:
	    usage(-1);
      }
   }

// Load configuration
   if (QuietMode == 0) fprintf(stderr, "Loading base configuration ... ");

   rc = conf_load(Config_path);
   if (rc < 0)
   {  fprintf(stderr, "FAILURE\n");
      syslog(LOG_ERR, "FAILURE - Can't load configuration");
      exit(-1);
   }
   if (QuietMode == 0) fprintf(stderr, "OK.\n");

   if (fSQL)
   {
      if (QuietMode == 0) fprintf(stderr, "Loading SQL configuration ... ");
      rc = cfg_load(Config_path, &config);
      if (rc < 0)
      {  fprintf(stderr, "ERROR (Fatal, see syslog).\n");
         exit(-1);
      }

      if (QuietMode == 0) fprintf(stderr, "OK.\nLoading scripts ... ");

      rc = qlist_load(config.DBscripts);
      if (rc < 0)
      {  fprintf(stderr, "ERROR (fatal)\n");
         exit(-1);
      }
      if (QuietMode == 0) fprintf(stderr, "OK.\n");

   } // if fSQL

// Converting old account table
   if (fConvert != 0)
   {  fprintf(stderr, "Converting database ... ");

// Open old account file
      rc = acc_baseopen(&Accbase_temp, accbase_name_old);
      if (rc != SUCCESS)
      {  fprintf(stderr, "FAILURE - Can't open old account table\n");
         exit(-1);
      } 

// Open new account file
      rc = acc_baseopen(&Accbase, conf_accfile);
      if (rc != SUCCESS)
      {  rc = open(conf_accfile, O_RDONLY | O_CREAT | O_EXCL, 0600);
         if (rc < 0)
         {  fprintf(stderr, "FAILURE - Can't open/create new account table\n");
            exit(-1);
         }
         close(rc);
         rc = acc_baseopen(&Accbase, conf_accfile);
         if (rc != SUCCESS)
         {  fprintf(stderr, "FAILURE - Can't open created account table\n");
            exit(-1);
         }
      }

// Ensure, that new table is empty
      rc = acc_reccount(&Accbase);
      if (rc != 0)
      {  fprintf(stderr, "FAILURE - New account table must be empty !\n");
         exit(-1);
      }

// Copy accounts data
      memset(&new_acc, 0, sizeof(new_acc));
      for(i=0; 1; i++)
      {  rc = acci_get_old(&Accbase_temp, i, &old_acc);
         if (rc == IO_ERROR)
         {  fprintf(stderr, "FAILURE - I/O error on read, (%d accounts copied) !\n", i);
            exit(-1);
         }
         if (rc == NOT_FOUND) break;
         new_acc.tag     = old_acc.tag;
         new_acc.accno   = old_acc.accno;
         new_acc.balance = old_acc.balance;
         new_acc.start   = old_acc.start;
         new_acc.stop    = old_acc.stop;
         new_acc.tariff  = old_acc.reserv[0];

         rc = acc_add(&Accbase, &new_acc);
         if (rc == IO_ERROR)
         {  fprintf(stderr, "FAILURE - I/O error on write, (%d accounts copied) !\n", i);
            exit(-1);
         }

         if (rc != i)
         {  fprintf(stderr, "FAILURE - Accno sync error (%d accounts copied) !\n", i);
            exit(-1);
         }
      }
      acc_baseclose(&Accbase_temp);
      acc_baseclose(&Accbase);
      fprintf(stderr, "SUCCESS (%d accounts copied) !\n", i);
      exit(-1);
   }

   if (fDaemon != 0 && ld->fStdio != 0)
   {  fprintf(stderr, "Can't daemonize in console mode\n");
      fDaemon = 0;
   }

// Load gates table (check file integrity)
   rc = reslinks_load(LOCK_SH);
   if (rc != SUCCESS)
   {  syslog(LOG_ERR, "Can't load gates file");
      exit (-1);
   }

   if (fDumpGates)
   {
      printf("SET client_encoding = 'KOI8';\n\n");
      printf("TRUNCATE beegates;\n");
      printf("COPY beegates (res_id, rid, acc_id, ident) FROM stdin;\n");
      for (i=0; i < linktabsz; i++)
      {
         printf ("%d\t%d\t%d\t%s\n", 
                   linktab[i].res_id,
                   linktab[i].user_id,
                   linktab[i].accno,
                   linktab[i].username);
      }
      printf("\\.\n");
      
      rc = acc_baseopen(&Accbase, conf_accfile);
      if (rc < 0)
      {  syslog(LOG_ERR, "Can't open account database");
         exit (-1);
      }

      printf("TRUNCATE beeaccs;\n");
      printf("COPY beeaccs (id, tag_deleted, tag_broken, tag_frozen, tag_off, tag_unlim, tag_payman, tag_log, "
             "balance, tariff_id, inetin_summ, inetout_summ, money_summ, tcredit "
             ") FROM stdin;\n");

      c = acc_reccount(&Accbase);

      for (i=0; i < c; i++)
      {
         rc = acc_get(&Accbase, i, &new_acc);  
         if (rc < 0 && rc > ACC_BROKEN) continue;

         printf ("%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%g\t%d\t%lld\t%lld\t%g\t%g\n",
                   i, 
                   new_acc.tag & ATAG_DELETED ? "t":"f",
                   new_acc.tag & ATAG_BROKEN  ? "t":"f",
                   new_acc.tag & ATAG_FROZEN  ? "t":"f",
                   new_acc.tag & ATAG_OFF     ? "t":"f",
                   new_acc.tag & ATAG_UNLIMIT ? "t":"f",
                   new_acc.tag & ATAG_PAYMAN  ? "t":"f",
                   new_acc.tag & ATAG_LOG     ? "t":"f",
                   new_acc.balance,
                   new_acc.tariff,
                   new_acc.inet_summ_in,
                   new_acc.inet_summ_out,
                   new_acc.money_summ,
                   new_acc.tcredit);
      }
      printf("\\.\n");
       
      exit(0);
   }

// Open database (to check & update if needed)
   rc = acc_baseopen(&Accbase, conf_accfile);
   if (rc < 0)
   {  syslog(LOG_ERR, "Can't open account database");
      exit (-1);
   }   
   rc = log_baseopen(&Logbase, conf_logfile);
   if (rc < 0)
   {  syslog(LOG_ERR, "Can't open log database");
      exit (-1);
   }   
   rc = tariffs_load(conf_tariffile);
   if (rc < 0)
   {  syslog(LOG_ERR, "Can't open tariff database");
      exit (-1);
   }   

   if (fSQL)
   {
      fprintf(stderr, "SQL init ... ");

   // Initialize connection
      DBdata = db2_init(config.DBtype, config.DBhost, config.DBname);
      if (DBdata == NULL)
      {  fprintf(stderr, "FAULT. db_init() fails.\n");
         exit (-1);
      }
   // Open database
      rc = db2_open(DBdata, config.DBlogin, config.DBpass);
      if (rc < 0)
      {  fprintf(stderr, "FAULT. db_open() fails.\n");
         exit (-1);
      }

      fprintf(stderr, "OK.\n");

// Perform immediate query from file
      if (QueryFilename != NULL)
      {  fd = open(QueryFilename, O_RDONLY, 0);
         if (fd >= 0)
         {  c = 0;
            rc = ioctl(fd, FIONREAD, &c);
            if (rc >= 0 && c > 1)
            {  QueryBuffer = (char*)calloc(1, c + 1);
               if (QueryBuffer != NULL)
               {  rc = read(fd, QueryBuffer, c);
                  if (rc == c)
                  {  if (DumpQuery) printf("%s", QueryBuffer);
                     rc = db2_execute(DBdata, "%s", QueryBuffer);
                     if (rc < 0) fprintf(stderr, "QUERY: SQL error\n");
                     else fprintf(stderr, "QUERY: done.\n"); 
                  }
                  else fprintf(stderr, "QUERY: File read error\n");
                  free(QueryBuffer);
                  QueryBuffer = NULL;
               }
               else fprintf(stderr, "QUERY: Memory allocation error\n");
            }
            else fprintf(stderr, "QUERY: File size error\n");
            close(fd);
         }
         else fprintf(stderr, "QUERY: File access error - %s\n", strerror(errno));
      }

// Perform test query
      row = db2_search(DBdata, 0, "SELECT count(*) FROM accs");
      if (row == NULL)
      {  fprintf(stderr, "Test fails.\n");
         exit (-1);
      }
      else fprintf(stderr, "Test OK. (%s accounts).\n", *row);
  
   } // if fSQL

// Update resources permissions
   if (fUpdate != 0) access_update(); 

// Close database
   acc_baseclose(&Accbase);
   log_baseclose(&Logbase);
   tariffs_free();

// Close database
   if (fSQL)
   {
      rc = db2_close(DBdata);
      if (rc < 0)
      {  fprintf(stderr, "FATAL: db2_close() fails.\n\n");
         exit (-1);
      }
   } // if fSQL

// Start server
   if (fRun)
   {  if (fDaemon)
      {  rc = daemon(0, 0);
         if (rc != SUCCESS)
         {  syslog(LOG_ERR, "Can't daemonize, closing");
            exit(-1);
         }
         if (proc_title == NULL) setproctitle("(daemon)");
         else setproctitle(proc_title);
      }
      if (setenv("HOME", "/root", 0) == (-1)) syslog(LOG_ERR, "setenv(): %m");
      rc = link_wait(ld, ForceService < 0 ? conf_coreport : ForceService);
      if (rc != -1)
      {  
         
         if (ld->fStdio == 0) setproctitle("(child)");
         else 
         {  if (proc_title == NULL) setproctitle("(console)");
            else setproctitle(proc_title);
         }

         cmd_out(RET_COMMENT, "Billing ver %d.%d.%d.%d", VER_VER, VER_SUBVER, VER_REV, VER_SUBREV);
         cmd_out(RET_COMMENT, "loading configuration ...");
         conf_free();
         rc = conf_load(Config_path);
         if (rc < 0)
         {  cmd_out(ERR_IOERROR, "failure");
            exit(-1);
         }
         cmd_out(RET_COMMENT, "loading gates ...");
// ReLoad linktable
         rc = reslinks_load(LOCK_SH);
         if (rc != SUCCESS)
         {  cmd_out(ERR_IOERROR, "failure: %s", strerror(errno));
            exit(-1);
         }
// Open database
         cmd_out(RET_COMMENT, "opening accounts ...");
         rc = acc_baseopen(&Accbase, conf_accfile);
         if (rc < 0)
         {  syslog(LOG_ERR, "Can't reopen account database");
            cmd_out(ERR_IOERROR, "failure: %s", strerror(errno));
            exit(-1);
         }
         cmd_out(RET_COMMENT, "opening log ...");
         rc = log_baseopen(&Logbase, conf_logfile);
         if (rc < 0)
         {  syslog(LOG_ERR, "Can't reopen log database");
            cmd_out(ERR_IOERROR, "failure: %s", strerror(errno));
            exit(-1);
         }
         cmd_out(RET_COMMENT, "loading tariffs ...");
         rc = tariffs_load(conf_tariffile);
         if (rc < 0)
         {  syslog(LOG_ERR, "Can't reopen tariff database");
            cmd_out(ERR_IOERROR, "failure");
            exit(-1);
         }

         if (fSQL)
         {
            cmd_out(RET_COMMENT, "connecting SQL ...");
            rc = db2_open(DBdata, config.DBlogin, config.DBpass);
            if (rc < 0)
            {  syslog(LOG_ERR, "Can't reopen SQL connection");
               cmd_out(ERR_IOERROR, "FAILURE");
               exit(-1);
            }

/*
            if (ld->fStdio)
            {  row = dbex_search(DBdata, 0, "log_session");
               if (row == NULL || row[0] == NULL)
               {  cmd_out(ERR_SYSTEM, "Session open failure");
                exit(-1);
               }
               SessionId = strtoll(row[0], NULL, 10);
               if (SessionId < 1)
               {  cmd_out(ERR_SYSTEM, "Session open failure (invalid id returned)");
                  exit(-1);
               }
               cmd_out(RET_COMMENT, "Log session (id: %lld)", SessionId);

               SessionPerm  = PERM_SUPERUSER;
               strlcpy(SessionLogin, "admin", sizeof(SessionLogin));
               UserId = 1;
               cmd_out(RET_COMMENT, "Root autologin ...");
            }
*/
         } // if fSQL
         cmd_out(RET_SUCCESS, "Ready");
         while(1)
         {  rc = link_gets(ld, sbuf, sizeof(sbuf));
            if (rc == LINK_DOWN) break;
            if (rc == SUCCESS) 
            {  rc = cmd_exec(sbuf, NULL);
               if (rc == LINK_DOWN || rc == CMD_EXIT) break;
            }
         }
      }
   }

// Close SQL connection
   if (fSQL) db2_close(DBdata);

   acc_baseclose(&Accbase);
   log_baseclose(&Logbase);

   return 0;
}