00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00040
00041
00042 #include "midas.h"
00043 #include "msystem.h"
00044
00045 #ifdef OS_UNIX
00046 #include <sys/mount.h>
00047 #endif
00048
00049 static INT ss_in_async_routine_flag = 0;
00050 #ifdef LOCAL_ROUTINES
00051 #include <signal.h>
00052
00053
00054
00055
00056
00057 BOOL disable_shm_write = FALSE;
00058
00059
00060 INT ss_set_async_flag(INT flag)
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 {
00081 INT old_flag;
00082
00083 old_flag = ss_in_async_routine_flag;
00084 ss_in_async_routine_flag = flag;
00085 return old_flag;
00086 }
00087
00088
00089 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 {
00114 INT status;
00115 char mem_name[256], file_name[256], path[256];
00116
00117
00118 sprintf(mem_name, "SM_%s", name);
00119
00120
00121 cm_get_path(path);
00122 if (path[0] == 0) {
00123 getcwd(path, 256);
00124 #if defined(OS_VMS)
00125 #elif defined(OS_UNIX)
00126 strcat(path, "/");
00127 #elif defined(OS_WINNT)
00128 strcat(path, "\\");
00129 #endif
00130 }
00131
00132 strcpy(file_name, path);
00133 #if defined (OS_UNIX)
00134 strcat(file_name, ".");
00135 #endif
00136 strcat(file_name, name);
00137 strcat(file_name, ".SHM");
00138
00139 #ifdef OS_WINNT
00140
00141 status = SS_SUCCESS;
00142
00143 {
00144 HANDLE hFile, hMap;
00145 char str[256], *p;
00146 DWORD file_size;
00147
00148
00149
00150
00151
00152 strcpy(str, path);
00153
00154
00155 while (strpbrk(str, "\\: "))
00156 *strpbrk(str, "\\: ") = '*';
00157 strcat(str, mem_name);
00158
00159
00160 p = str;
00161 while (*p)
00162 *p++ = (char) toupper(*p);
00163
00164 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00165 if (hMap == 0) {
00166 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00167 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00168 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00169 if (!hFile) {
00170 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00171 return SS_FILE_ERROR;
00172 }
00173
00174 file_size = GetFileSize(hFile, NULL);
00175 if (file_size != 0xFFFFFFFF && file_size > 0)
00176 size = file_size;
00177
00178 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00179
00180 if (!hMap) {
00181 status = GetLastError();
00182 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
00183 return SS_FILE_ERROR;
00184 }
00185
00186 CloseHandle(hFile);
00187 status = SS_CREATED;
00188 }
00189
00190 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00191 *handle = (HNDLE) hMap;
00192
00193 if (adr == NULL) {
00194 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00195 return SS_NO_MEMORY;
00196 }
00197
00198 return status;
00199 }
00200
00201 #endif
00202 #ifdef OS_VMS
00203
00204 status = SS_SUCCESS;
00205
00206 {
00207 int addr[2];
00208 $DESCRIPTOR(memname_dsc, "dummy");
00209 $DESCRIPTOR(filename_dsc, "dummy");
00210 memname_dsc.dsc$w_length = strlen(mem_name);
00211 memname_dsc.dsc$a_pointer = mem_name;
00212 filename_dsc.dsc$w_length = strlen(file_name);
00213 filename_dsc.dsc$a_pointer = file_name;
00214
00215 addr[0] = size;
00216 addr[1] = 0;
00217
00218 status = ppl$create_shared_memory(&memname_dsc, addr, &PPL$M_NOUNI, &filename_dsc);
00219
00220 if (status == PPL$_CREATED)
00221 status = SS_CREATED;
00222 else if (status != PPL$_NORMAL)
00223 status = SS_FILE_ERROR;
00224
00225 *adr = (void *) addr[1];
00226 *handle = 0;
00227
00228 if (adr == NULL)
00229 return SS_NO_MEMORY;
00230
00231 return status;
00232 }
00233
00234 #endif
00235 #ifdef OS_UNIX
00236
00237 status = SS_SUCCESS;
00238
00239 {
00240 int key, shmid, fh, file_size;
00241 struct shmid_ds buf;
00242
00243
00244 key = ftok(file_name, 'M');
00245
00246
00247 if (key == -1) {
00248 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00249 close(fh);
00250 key = ftok(file_name, 'M');
00251
00252 if (key == -1) {
00253 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00254 return SS_FILE_ERROR;
00255 }
00256
00257 status = SS_CREATED;
00258
00259
00260
00261 shmid = shmget(key, 0, 0);
00262 shmctl(shmid, IPC_RMID, &buf);
00263 } else {
00264
00265 file_size = (INT) ss_file_size(file_name);
00266 if (file_size > 0) {
00267 if (file_size < size) {
00268 cm_msg(MERROR, "ss_shm_open", "Shared memory segment \'%s\' size %d is smaller than requested size %d. Please remove it and try again",file_name,file_size,size);
00269 return SS_NO_MEMORY;
00270 }
00271
00272 size = file_size;
00273 }
00274 }
00275
00276
00277 shmid = shmget(key, size, 0);
00278 if (shmid == -1) {
00279
00280 shmid = shmget(key, size, IPC_CREAT|IPC_EXCL);
00281 if (shmid == -1 && errno == EEXIST)
00282 {
00283 cm_msg(MERROR, "ss_shm_open", "Shared memory segment with key 0x%x already exists, please remove it manually: ipcrm -M 0x%x",key,key);
00284 return SS_NO_MEMORY;
00285 }
00286 status = SS_CREATED;
00287 }
00288
00289 if (shmid == -1) {
00290 cm_msg(MERROR, "ss_shm_open", "shmget(key=0x%x,size=%d) failed, errno %d (%s)", key, size, errno, strerror(errno));
00291 return SS_NO_MEMORY;
00292 }
00293
00294 buf.shm_perm.uid = getuid();
00295 buf.shm_perm.gid = getgid();
00296 buf.shm_perm.mode = 0666;
00297 shmctl(shmid, IPC_SET, &buf);
00298
00299 *adr = shmat(shmid, 0, 0);
00300 *handle = (HNDLE) shmid;
00301
00302 if ((*adr) == (void *) (-1)) {
00303 cm_msg(MERROR, "ss_shm_open","shmat(shmid=%d) failed, errno %d (%s)", shmid, errno, strerror(errno));
00304 return SS_NO_MEMORY;
00305 }
00306
00307
00308 if (status == SS_CREATED) {
00309 fh = open(file_name, O_RDONLY, 0644);
00310 if (fh == -1)
00311 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00312 else
00313 read(fh, *adr, size);
00314 close(fh);
00315 }
00316
00317 return status;
00318 }
00319
00320 #endif
00321 }
00322
00323
00324 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 {
00349 char mem_name[256], file_name[256], path[256];
00350
00351
00352
00353
00354
00355 sprintf(mem_name, "SM_%s", name);
00356
00357
00358 cm_get_path(path);
00359 if (path[0] == 0) {
00360 getcwd(path, 256);
00361 #if defined(OS_VMS)
00362 #elif defined(OS_UNIX)
00363 strcat(path, "/");
00364 #elif defined(OS_WINNT)
00365 strcat(path, "\\");
00366 #endif
00367 }
00368
00369 strcpy(file_name, path);
00370 #if defined (OS_UNIX)
00371 strcat(file_name, ".");
00372 #endif
00373 strcat(file_name, name);
00374 strcat(file_name, ".SHM");
00375
00376 #ifdef OS_WINNT
00377
00378 if (!UnmapViewOfFile(adr))
00379 return SS_INVALID_ADDRESS;
00380
00381 CloseHandle((HANDLE) handle);
00382
00383 return SS_SUCCESS;
00384
00385 #endif
00386 #ifdef OS_VMS
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 return SS_INVALID_ADDRESS;
00411
00412 #endif
00413 #ifdef OS_UNIX
00414
00415 {
00416 struct shmid_ds buf;
00417 FILE *fh;
00418
00419
00420 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00421 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_STAT) failed, errno %d (%s)",handle,errno,strerror(errno));
00422 return SS_INVALID_HANDLE;
00423 }
00424
00425
00426 if (buf.shm_nattch == 1) {
00427 if (!disable_shm_write) {
00428 fh = fopen(file_name, "w");
00429
00430 if (fh == NULL) {
00431 cm_msg(MERROR, "ss_shm_close",
00432 "Cannot write to file %s, please check protection", file_name);
00433 } else {
00434
00435 fwrite(adr, 1, buf.shm_segsz, fh);
00436 fclose(fh);
00437 }
00438 }
00439
00440 if (shmdt(adr) < 0) {
00441 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00442 return SS_INVALID_ADDRESS;
00443 }
00444
00445 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00446 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_RMID) failed, errno %d (%s)",handle,errno,strerror(errno));
00447 return SS_INVALID_ADDRESS;
00448 }
00449 } else
00450
00451 if (shmdt(adr) < 0) {
00452 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00453 return SS_INVALID_ADDRESS;
00454 }
00455
00456 return SS_SUCCESS;
00457 }
00458
00459 #endif
00460 }
00461
00462
00463 INT ss_shm_protect(HNDLE handle, void *adr)
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 {
00484 #ifdef OS_WINNT
00485
00486 if (!UnmapViewOfFile(adr))
00487 return SS_INVALID_ADDRESS;
00488
00489 #endif
00490 #ifdef OS_UNIX
00491
00492 if (shmdt(adr) < 0) {
00493 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00494 return SS_INVALID_ADDRESS;
00495 }
00496 #endif
00497 return SS_SUCCESS;
00498 }
00499
00500
00501 INT ss_shm_unprotect(HNDLE handle, void **adr)
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 {
00522 #ifdef OS_WINNT
00523
00524 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00525
00526 if (*adr == NULL) {
00527 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00528 return SS_NO_MEMORY;
00529 }
00530 #endif
00531 #ifdef OS_UNIX
00532
00533 *adr = shmat(handle, 0, 0);
00534
00535 if ((*adr) == (void *) (-1)) {
00536 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
00537 return SS_NO_MEMORY;
00538 }
00539 #endif
00540
00541 return SS_SUCCESS;
00542 }
00543
00544
00545 INT ss_shm_flush(char *name, void *adr, INT size)
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 {
00566 char mem_name[256], file_name[256], path[256];
00567
00568
00569
00570
00571
00572 sprintf(mem_name, "SM_%s", name);
00573
00574
00575 cm_get_path(path);
00576 if (path[0] == 0) {
00577 getcwd(path, 256);
00578 #if defined(OS_VMS)
00579 #elif defined(OS_UNIX)
00580 strcat(path, "/");
00581 #elif defined(OS_WINNT)
00582 strcat(path, "\\");
00583 #endif
00584 }
00585
00586 strcpy(file_name, path);
00587 #if defined (OS_UNIX)
00588 strcat(file_name, ".");
00589 #endif
00590 strcat(file_name, name);
00591 strcat(file_name, ".SHM");
00592
00593 #ifdef OS_WINNT
00594
00595 if (!FlushViewOfFile(adr, size))
00596 return SS_INVALID_ADDRESS;
00597
00598 return SS_SUCCESS;
00599
00600 #endif
00601 #ifdef OS_VMS
00602
00603 return SS_SUCCESS;
00604
00605 #endif
00606 #ifdef OS_UNIX
00607
00608 if (!disable_shm_write) {
00609 FILE *fh;
00610
00611 fh = fopen(file_name, "w");
00612
00613 if (fh == NULL) {
00614 cm_msg(MERROR, "ss_shm_flush",
00615 "Cannot write to file %s, please check protection", file_name);
00616 } else {
00617
00618 fwrite(adr, 1, size, fh);
00619 fclose(fh);
00620 }
00621 }
00622 return SS_SUCCESS;
00623
00624 #endif
00625 }
00626
00627
00628 INT ss_getthandle(void)
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 {
00646 #ifdef OS_WINNT
00647 HANDLE hThread;
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00659 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS, TRUE, 0);
00660
00661 return (INT)hThread;
00662
00663 #endif
00664 #ifdef OS_VMS
00665
00666 return 0;
00667
00668 #endif
00669 #ifdef OS_UNIX
00670
00671 return ss_getpid();
00672
00673 #endif
00674 }
00675
00676 #endif
00677
00678
00679 struct {
00680 char c;
00681 double d;
00682 } test_align;
00683
00684 INT ss_get_struct_align()
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 {
00707 return (PTYPE) (&test_align.d) - (PTYPE) & test_align.c;
00708 }
00709
00710
00711 INT ss_getpid(void)
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 {
00729 #ifdef OS_WINNT
00730
00731 return (int) GetCurrentProcessId();
00732
00733 #endif
00734 #ifdef OS_VMS
00735
00736 return getpid();
00737
00738 #endif
00739 #ifdef OS_UNIX
00740
00741 return getpid();
00742
00743 #endif
00744 #ifdef OS_VXWORKS
00745
00746 return 0;
00747
00748 #endif
00749 #ifdef OS_MSDOS
00750
00751 return 0;
00752
00753 #endif
00754 }
00755
00756
00757
00758 static BOOL _single_thread = FALSE;
00759
00760 void ss_force_single_thread()
00761 {
00762 _single_thread = TRUE;
00763 }
00764
00765 INT ss_gettid(void)
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 {
00783
00784 if (_single_thread)
00785 return 1;
00786
00787 #ifdef OS_MSDOS
00788
00789 return 0;
00790
00791 #endif
00792 #ifdef OS_WINNT
00793
00794 return (int) GetCurrentThreadId();
00795
00796 #endif
00797 #ifdef OS_VMS
00798
00799 return ss_getpid();
00800
00801 #endif
00802 #ifdef OS_UNIX
00803
00804 return ss_getpid();
00805
00806 #endif
00807 #ifdef OS_VXWORKS
00808
00809 return ss_getpid();
00810
00811 #endif
00812 }
00813
00814
00815
00816 #ifdef OS_UNIX
00817 void catch_sigchld(int signo)
00818 {
00819 int status;
00820
00821 wait(&status);
00822 return;
00823 }
00824 #endif
00825
00826 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 {
00850 #ifdef OS_WINNT
00851
00852 if (spawnvp(mode, cmdname, argv) < 0)
00853 return SS_INVALID_NAME;
00854
00855 return SS_SUCCESS;
00856
00857 #endif
00858
00859 #ifdef OS_MSDOS
00860
00861 spawnvp((int) mode, cmdname, argv);
00862
00863 return SS_SUCCESS;
00864
00865 #endif
00866
00867 #ifdef OS_VMS
00868
00869 {
00870 char cmdstring[500], *pc;
00871 INT i, flags, status;
00872 va_list argptr;
00873
00874 $DESCRIPTOR(cmdstring_dsc, "dummy");
00875
00876 if (mode & P_DETACH) {
00877 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
00878 cmdstring_dsc.dsc$a_pointer = cmdstring;
00879
00880 status = sys$creprc(0, &cmdstring_dsc,
00881 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
00882 } else {
00883 flags = (mode & P_NOWAIT) ? 1 : 0;
00884
00885 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
00886 if (*pc == ']')
00887 pc++;
00888
00889 strcpy(cmdstring, pc);
00890
00891 if (strchr(cmdstring, ';'))
00892 *strchr(cmdstring, ';') = 0;
00893
00894 strcat(cmdstring, " ");
00895
00896 for (i = 1; argv[i] != NULL; i++) {
00897 strcat(cmdstring, argv[i]);
00898 strcat(cmdstring, " ");
00899 }
00900
00901 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
00902 cmdstring_dsc.dsc$a_pointer = cmdstring;
00903
00904 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
00905 }
00906
00907 return BM_SUCCESS;
00908 }
00909
00910 #endif
00911 #ifdef OS_UNIX
00912 pid_t child_pid;
00913
00914 #ifdef OS_ULTRIX
00915 union wait *status;
00916 #else
00917 int status;
00918 #endif
00919
00920 if ((child_pid = fork()) < 0)
00921 return (-1);
00922
00923 if (child_pid == 0) {
00924
00925 child_pid = execvp(cmdname, argv);
00926 return SS_SUCCESS;
00927 } else {
00928
00929 if (mode == P_WAIT)
00930 #ifdef OS_ULTRIX
00931 waitpid(child_pid, status, WNOHANG);
00932 #else
00933 waitpid(child_pid, &status, WNOHANG);
00934 #endif
00935
00936 else
00937
00938 signal(SIGCHLD, catch_sigchld);
00939 }
00940
00941 return SS_SUCCESS;
00942
00943 #endif
00944 }
00945
00946
00947 INT ss_shell(int sock)
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 {
00965 #ifdef OS_WINNT
00966
00967 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
00968 hChildStdoutRd, hChildStdoutWr,
00969 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
00970
00971 SECURITY_ATTRIBUTES saAttr;
00972 PROCESS_INFORMATION piProcInfo;
00973 STARTUPINFO siStartInfo;
00974 char buffer[256], cmd[256];
00975 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
00976 fd_set readfds;
00977 struct timeval timeout;
00978
00979
00980 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
00981 saAttr.bInheritHandle = TRUE;
00982 saAttr.lpSecurityDescriptor = NULL;
00983
00984
00985 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
00986
00987
00988 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
00989 return 0;
00990
00991
00992 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
00993 return 0;
00994
00995
00996
00997 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
00998
00999
01000 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01001 return 0;
01002
01003
01004 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01005 return 0;
01006
01007
01008
01009 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01010
01011
01012 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01013 return 0;
01014
01015
01016 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01017 return 0;
01018
01019
01020 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01021 DUPLICATE_SAME_ACCESS))
01022 return 0;
01023
01024 CloseHandle(hChildStdinWr);
01025
01026
01027 memset(&siStartInfo, 0, sizeof(siStartInfo));
01028 siStartInfo.cb = sizeof(STARTUPINFO);
01029 siStartInfo.lpReserved = NULL;
01030 siStartInfo.lpReserved2 = NULL;
01031 siStartInfo.cbReserved2 = 0;
01032 siStartInfo.lpDesktop = NULL;
01033 siStartInfo.dwFlags = 0;
01034
01035 if (!CreateProcess(NULL, "cmd /Q",
01036 NULL,
01037 NULL,
01038 TRUE,
01039 0,
01040 NULL,
01041 NULL,
01042 &siStartInfo,
01043 &piProcInfo))
01044 return 0;
01045
01046
01047 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01048 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01049 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01050
01051 i_cmd = 0;
01052
01053 do {
01054
01055 do {
01056 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01057 break;
01058
01059 if (dwRead > 0) {
01060 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01061 send(sock, buffer, dwRead, 0);
01062 }
01063 } while (dwAvail > 0);
01064
01065
01066 do {
01067 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01068 break;
01069 if (dwRead > 0) {
01070 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01071 send(sock, buffer, dwRead, 0);
01072 }
01073 } while (dwAvail > 0);
01074
01075
01076
01077 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01078 break;
01079 if (i != STILL_ACTIVE)
01080 break;
01081
01082
01083 FD_ZERO(&readfds);
01084 FD_SET(sock, &readfds);
01085 timeout.tv_sec = 0;
01086 timeout.tv_usec = 100;
01087 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01088
01089 if (FD_ISSET(sock, &readfds)) {
01090 i = recv(sock, cmd + i_cmd, 1, 0);
01091 if (i <= 0)
01092 break;
01093
01094
01095 if (cmd[i_cmd] == 8) {
01096 if (i_cmd > 0) {
01097 send(sock, "\b \b", 3, 0);
01098 i_cmd -= 1;
01099 }
01100 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01101 send(sock, cmd + i_cmd, 1, 0);
01102 i_cmd += i;
01103 }
01104 }
01105
01106
01107 if (cmd[i_cmd - 1] == 10) {
01108 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01109 i_cmd = 0;
01110 }
01111
01112 } while (TRUE);
01113
01114 CloseHandle(hChildStdinWrDup);
01115 CloseHandle(hChildStdinRd);
01116 CloseHandle(hChildStderrRd);
01117 CloseHandle(hChildStdoutRd);
01118
01119 return SS_SUCCESS;
01120
01121 #endif
01122
01123 #ifdef OS_UNIX
01124 #ifndef NO_PTY
01125 pid_t pid;
01126 int i, pipe;
01127 char line[32], buffer[1024], shell[32];
01128 fd_set readfds;
01129
01130 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01131 return 0;
01132 else if (pid > 0) {
01133
01134
01135 do {
01136 FD_ZERO(&readfds);
01137 FD_SET(sock, &readfds);
01138 FD_SET(pipe, &readfds);
01139
01140 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01141
01142 if (FD_ISSET(sock, &readfds)) {
01143 memset(buffer, 0, sizeof(buffer));
01144 i = recv(sock, buffer, sizeof(buffer), 0);
01145 if (i <= 0)
01146 break;
01147 if (write(pipe, buffer, i) != i)
01148 break;
01149 }
01150
01151 if (FD_ISSET(pipe, &readfds)) {
01152 memset(buffer, 0, sizeof(buffer));
01153 i = read(pipe, buffer, sizeof(buffer));
01154 if (i <= 0)
01155 break;
01156 send(sock, buffer, i, 0);
01157 }
01158
01159 } while (1);
01160 } else {
01161
01162
01163 if (getenv("SHELL"))
01164 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01165 else
01166 strcpy(shell, "/bin/sh");
01167 execl(shell, shell, 0);
01168 }
01169 #else
01170 send(sock, "not implemented\n", 17, 0);
01171 #endif
01172
01173 return SS_SUCCESS;
01174
01175 #endif
01176 }
01177
01178
01179 static BOOL _daemon_flag;
01180
01181 INT ss_daemon_init(BOOL keep_stdout)
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 {
01200 #ifdef OS_UNIX
01201
01202
01203 int i, fd, pid;
01204
01205 if ((pid = fork()) < 0)
01206 return SS_ABORT;
01207 else if (pid != 0)
01208 exit(0);
01209
01210
01211
01212 _daemon_flag = TRUE;
01213
01214
01215
01216 for (i = 0; i < 3; i++) {
01217 if (keep_stdout && ((i == 1) || (i == 2)))
01218 continue;
01219
01220 close(i);
01221 fd = open("/dev/null", O_RDWR, 0);
01222 if (fd < 0)
01223 fd = open("/dev/null", O_WRONLY, 0);
01224 if (fd < 0) {
01225 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01226 return SS_ABORT;
01227 }
01228 if (fd != i) {
01229 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01230 return SS_ABORT;
01231 }
01232 }
01233
01234 setsid();
01235 umask(0);
01236
01237 #endif
01238
01239 return SS_SUCCESS;
01240 }
01241
01242
01243 BOOL ss_existpid(INT pid)
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 {
01262 #ifdef OS_UNIX
01263
01264 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01265 #else
01266 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01267 return FALSE;
01268 #endif
01269 }
01270
01271
01272
01273 #endif
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 INT ss_system(char *command)
01294 {
01295 #ifdef OS_UNIX
01296 INT childpid;
01297
01298 return ss_exec(command, &childpid);
01299
01300 #else
01301
01302 system(command);
01303 return SS_SUCCESS;
01304
01305 #endif
01306 }
01307
01308
01309 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01310
01311
01312 INT ss_exec(char *command, INT * pid)
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 {
01332 #ifdef OS_UNIX
01333
01334
01335 int i, fd;
01336
01337 if ((*pid = fork()) < 0)
01338 return SS_ABORT;
01339 else if (*pid != 0) {
01340
01341 signal(SIGCHLD, catch_sigchld);
01342 return SS_SUCCESS;
01343 }
01344
01345
01346
01347
01348 for (i = 0; i < 256; i++)
01349 close(i);
01350
01351
01352
01353 for (i = 0; i < 3; i++) {
01354 fd = open("/dev/null", O_RDWR, 0);
01355 if (fd < 0)
01356 fd = open("/dev/null", O_WRONLY, 0);
01357 if (fd < 0) {
01358 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01359 return SS_ABORT;
01360 }
01361 if (fd != i) {
01362 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01363 return SS_ABORT;
01364 }
01365 }
01366
01367 setsid();
01368
01369 umask(0);
01370
01371
01372 execl("/bin/sh", "sh", "-c", command, NULL);
01373
01374 #else
01375
01376 system(command);
01377
01378 #endif
01379
01380 return SS_SUCCESS;
01381 }
01382
01383
01384 #endif
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419 midas_thread_t ss_thread_create(INT(*thread_func) (void *), void *param)
01420 {
01421 #if defined(OS_WINNT)
01422
01423 HANDLE status;
01424 DWORD thread_id;
01425
01426 if (thread_func == NULL) {
01427 return 0;
01428 }
01429
01430 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01431 (LPVOID) param, 0, &thread_id);
01432
01433 return status == NULL ? 0 : (midas_thread_t)thread_id;
01434
01435 #elif defined(OS_MSDOS)
01436
01437 return 0;
01438
01439 #elif defined(OS_VMS)
01440
01441 return 0;
01442
01443 #elif defined(OS_VXWORKS)
01444
01445
01446
01447
01448
01449
01450
01451
01452 INT status;
01453 VX_TASK_SPAWN *ts;
01454
01455 ts = (VX_TASK_SPAWN *) param;
01456 status =
01457 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01458 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01459 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
01460
01461 return status == ERROR ? 0 : status;
01462
01463 #elif defined(OS_UNIX)
01464
01465 INT status;
01466 pthread_t thread_id;
01467
01468 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01469
01470 return status != 0 ? 0 : thread_id;
01471
01472 #endif
01473 }
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 INT ss_thread_kill(midas_thread_t thread_id)
01494 {
01495 #if defined(OS_WINNT)
01496
01497 DWORD status;
01498
01499 status = TerminateThread(thread_id, 0);
01500
01501 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01502
01503 #elif defined(OS_MSDOS)
01504
01505 return 0;
01506
01507 #elif defined(OS_VMS)
01508
01509 return 0;
01510
01511 #elif defined(OS_VXWORKS)
01512
01513 INT status;
01514 status = taskDelete(thread_id);
01515 return status == OK ? 0 : ERROR;
01516
01517 #elif defined(OS_UNIX)
01518
01519 INT status;
01520 status = pthread_kill(thread_id, SIGKILL);
01521 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01522
01523 #endif
01524 }
01525
01526
01527 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01528
01529
01530 static INT skip_mutex_handle = -1;
01531
01532 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559 {
01560 char mutex_name[256], path[256], file_name[256];
01561
01562
01563 sprintf(mutex_name, "MX_%s", name);
01564
01565 #ifdef OS_VXWORKS
01566
01567
01568
01569 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01570 return SS_NO_MUTEX;
01571 return SS_CREATED;
01572
01573 #endif
01574
01575
01576 cm_get_path(path);
01577 if (path[0] == 0) {
01578 getcwd(path, 256);
01579 #if defined(OS_VMS)
01580 #elif defined(OS_UNIX)
01581 strcat(path, "/");
01582 #elif defined(OS_WINNT)
01583 strcat(path, "\\");
01584 #endif
01585 }
01586
01587 strcpy(file_name, path);
01588 #if defined (OS_UNIX)
01589 strcat(file_name, ".");
01590 #endif
01591 strcat(file_name, name);
01592 strcat(file_name, ".SHM");
01593
01594 #ifdef OS_WINNT
01595
01596 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01597
01598 if (*mutex_handle == 0)
01599 return SS_NO_MUTEX;
01600
01601 return SS_CREATED;
01602
01603 #endif
01604 #ifdef OS_VMS
01605
01606
01607
01608 {
01609 INT status;
01610 $DESCRIPTOR(mutexname_dsc, "dummy");
01611 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01612 mutexname_dsc.dsc$a_pointer = mutex_name;
01613
01614 *mutex_handle = (HNDLE) malloc(8);
01615
01616 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01617 0, 0, 0, 0, 0, 0);
01618
01619 if (status != SS$_NORMAL) {
01620 free((void *) *mutex_handle);
01621 *mutex_handle = 0;
01622 }
01623
01624 if (*mutex_handle == 0)
01625 return SS_NO_MUTEX;
01626
01627 return SS_CREATED;
01628 }
01629
01630 #endif
01631 #ifdef OS_UNIX
01632
01633 {
01634 INT key, status, fh;
01635 struct semid_ds buf;
01636
01637 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01638 union semun arg;
01639 #else
01640 union semun {
01641 INT val;
01642 struct semid_ds *buf;
01643 ushort *array;
01644 } arg;
01645 #endif
01646
01647 status = SS_SUCCESS;
01648
01649
01650 key = ftok(file_name, 'M');
01651 if (key < 0) {
01652 fh = open(file_name, O_CREAT, 0644);
01653 close(fh);
01654 key = ftok(file_name, 'M');
01655 status = SS_CREATED;
01656 }
01657
01658
01659 *mutex_handle = (HNDLE) semget(key, 1, 0);
01660 if (*mutex_handle < 0) {
01661 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01662 status = SS_CREATED;
01663 }
01664
01665 if (*mutex_handle < 0) {
01666 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d", errno);
01667 return SS_NO_MUTEX;
01668 }
01669
01670 buf.sem_perm.uid = getuid();
01671 buf.sem_perm.gid = getgid();
01672 buf.sem_perm.mode = 0666;
01673 arg.buf = &buf;
01674
01675 semctl(*mutex_handle, 0, IPC_SET, arg);
01676
01677
01678 if (status == SS_CREATED) {
01679 arg.val = 1;
01680 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01681 return SS_NO_MUTEX;
01682 }
01683
01684 return SS_SUCCESS;
01685 }
01686 #endif
01687
01688 #ifdef OS_MSDOS
01689 return SS_NO_MUTEX;
01690 #endif
01691 }
01692
01693
01694 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714 {
01715 INT status;
01716
01717 #ifdef OS_WINNT
01718
01719 status = WaitForSingleObject((HANDLE) mutex_handle, timeout == 0 ? INFINITE : timeout);
01720 if (status == WAIT_FAILED)
01721 return SS_NO_MUTEX;
01722 if (status == WAIT_TIMEOUT)
01723 return SS_TIMEOUT;
01724
01725 return SS_SUCCESS;
01726 #endif
01727 #ifdef OS_VMS
01728 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
01729 if (status != SS$_NORMAL)
01730 return SS_NO_MUTEX;
01731 return SS_SUCCESS;
01732
01733 #endif
01734 #ifdef OS_VXWORKS
01735
01736 status = semTake((SEM_ID) mutex_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
01737 if (status == ERROR)
01738 return SS_NO_MUTEX;
01739 return SS_SUCCESS;
01740
01741 #endif
01742 #ifdef OS_UNIX
01743 {
01744 DWORD start_time;
01745 struct sembuf sb;
01746
01747 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01748 union semun arg;
01749 #else
01750 union semun {
01751 INT val;
01752 struct semid_ds *buf;
01753 ushort *array;
01754 } arg;
01755 #endif
01756
01757 sb.sem_num = 0;
01758 sb.sem_op = -1;
01759 sb.sem_flg = SEM_UNDO;
01760
01761 memset(&arg, 0, sizeof(arg));
01762
01763
01764
01765 if (ss_in_async_routine_flag)
01766 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
01767 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
01768 skip_mutex_handle = mutex_handle;
01769 return SS_SUCCESS;
01770 }
01771
01772 skip_mutex_handle = -1;
01773
01774 start_time = ss_millitime();
01775
01776 do {
01777 status = semop(mutex_handle, &sb, 1);
01778
01779
01780 if (status == 0)
01781 break;
01782
01783
01784 if (errno == EINTR) {
01785
01786 if (timeout > 0 && ss_millitime() - start_time > timeout)
01787 return SS_TIMEOUT;
01788
01789 continue;
01790 }
01791
01792 return SS_NO_MUTEX;
01793 } while (1);
01794
01795 return SS_SUCCESS;
01796 }
01797 #endif
01798
01799 #ifdef OS_MSDOS
01800 return SS_NO_MUTEX;
01801 #endif
01802 }
01803
01804
01805 INT ss_mutex_release(HNDLE mutex_handle)
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823 {
01824 INT status;
01825
01826 #ifdef OS_WINNT
01827
01828 status = ReleaseMutex((HANDLE) mutex_handle);
01829
01830 if (status == FALSE)
01831 return SS_NO_MUTEX;
01832
01833 return SS_SUCCESS;
01834
01835 #endif
01836 #ifdef OS_VMS
01837
01838 status = sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
01839
01840 if (status != SS$_NORMAL)
01841 return SS_NO_MUTEX;
01842
01843 return SS_SUCCESS;
01844
01845 #endif
01846
01847 #ifdef OS_VXWORKS
01848
01849 if (semGive((SEM_ID) mutex_handle) == ERROR)
01850 return SS_NO_MUTEX;
01851 return SS_SUCCESS;
01852 #endif
01853
01854 #ifdef OS_UNIX
01855 {
01856 struct sembuf sb;
01857
01858 sb.sem_num = 0;
01859 sb.sem_op = 1;
01860 sb.sem_flg = SEM_UNDO;
01861
01862 if (mutex_handle == skip_mutex_handle) {
01863 skip_mutex_handle = -1;
01864 return SS_SUCCESS;
01865 }
01866
01867 do {
01868 status = semop(mutex_handle, &sb, 1);
01869
01870
01871 if (status == 0)
01872 break;
01873
01874
01875 if (errno == EINTR)
01876 continue;
01877
01878 return SS_NO_MUTEX;
01879 } while (1);
01880
01881 return SS_SUCCESS;
01882 }
01883 #endif
01884
01885 #ifdef OS_MSDOS
01886 return SS_NO_MUTEX;
01887 #endif
01888 }
01889
01890
01891 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909 {
01910 #ifdef OS_WINNT
01911
01912 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
01913 return SS_NO_MUTEX;
01914
01915 return SS_SUCCESS;
01916
01917 #endif
01918 #ifdef OS_VMS
01919
01920 free((void *) mutex_handle);
01921 return SS_SUCCESS;
01922
01923 #endif
01924
01925 #ifdef OS_VXWORKS
01926
01927 if (semDelete((SEM_ID) mutex_handle) == ERROR)
01928 return SS_NO_MUTEX;
01929 return SS_SUCCESS;
01930 #endif
01931
01932 #ifdef OS_UNIX
01933 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01934 union semun arg;
01935 #else
01936 union semun {
01937 INT val;
01938 struct semid_ds *buf;
01939 ushort *array;
01940 } arg;
01941 #endif
01942
01943 memset(&arg, 0, sizeof(arg));
01944
01945 if (destroy_flag)
01946 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
01947 return SS_NO_MUTEX;
01948
01949 return SS_SUCCESS;
01950
01951 #endif
01952
01953 #ifdef OS_MSDOS
01954 return SS_NO_MUTEX;
01955 #endif
01956 }
01957
01958
01959 #endif
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979 DWORD ss_millitime()
01980 {
01981 #ifdef OS_WINNT
01982
01983 return (int) GetTickCount();
01984
01985 #endif
01986 #ifdef OS_MSDOS
01987
01988 return clock() * 55;
01989
01990 #endif
01991 #ifdef OS_VMS
01992
01993 {
01994 char time[8];
01995 DWORD lo, hi;
01996
01997 sys$gettim(time);
01998
01999 lo = *((DWORD *) time);
02000 hi = *((DWORD *) (time + 4));
02001
02002
02003
02004 return lo / 10000 + hi * 429496.7296;
02005
02006 }
02007
02008 #endif
02009 #ifdef OS_UNIX
02010 {
02011 struct timeval tv;
02012
02013 gettimeofday(&tv, NULL);
02014
02015 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02016 }
02017
02018 #endif
02019 #ifdef OS_VXWORKS
02020 {
02021 int count;
02022 static int ticks_per_msec = 0;
02023
02024 if (ticks_per_msec == 0)
02025 ticks_per_msec = 1000 / sysClkRateGet();
02026
02027 return tickGet() * ticks_per_msec;
02028 }
02029 #endif
02030 }
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046 DWORD ss_time()
02047 {
02048 #if !defined(OS_VXWORKS)
02049 #if !defined(OS_VMS)
02050 tzset();
02051 #endif
02052 #endif
02053 return (DWORD) time(NULL);
02054 }
02055
02056
02057 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02058
02059
02060 DWORD ss_settime(DWORD seconds)
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076 {
02077 #if defined(OS_WINNT)
02078 SYSTEMTIME st;
02079 struct tm *ltm;
02080
02081 tzset();
02082 ltm = localtime((time_t *) & seconds);
02083
02084 st.wYear = ltm->tm_year + 1900;
02085 st.wMonth = ltm->tm_mon + 1;
02086 st.wDay = ltm->tm_mday;
02087 st.wHour = ltm->tm_hour;
02088 st.wMinute = ltm->tm_min;
02089 st.wSecond = ltm->tm_sec;
02090 st.wMilliseconds = 0;
02091
02092 SetLocalTime(&st);
02093
02094 #elif defined(OS_DARWIN)
02095
02096 assert(!"ss_settime() is not supported");
02097
02098 return SS_NO_DRIVER;
02099
02100 #elif defined(OS_UNIX)
02101
02102 stime((time_t *) & seconds);
02103
02104 #elif defined(OS_VXWORKS)
02105
02106 struct timespec ltm;
02107
02108 ltm.tv_sec = seconds;
02109 ltm.tv_nsec = 0;
02110 clock_settime(CLOCK_REALTIME, <m);
02111
02112 #endif
02113 return SS_SUCCESS;
02114 }
02115
02116
02117 char *ss_asctime()
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134 {
02135 static char str[32];
02136 time_t seconds;
02137
02138 seconds = (time_t) ss_time();
02139
02140 #if !defined(OS_VXWORKS)
02141 #if !defined(OS_VMS)
02142 tzset();
02143 #endif
02144 #endif
02145 strcpy(str, asctime(localtime(&seconds)));
02146
02147
02148 str[24] = 0;
02149
02150 return str;
02151 }
02152
02153
02154 INT ss_timezone()
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172 {
02173 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
02174 return 0;
02175 #else
02176 return timezone;
02177 #endif
02178 }
02179
02180
02181
02182
02183 #ifdef OS_UNIX
02184
02185 void ss_cont()
02186 {
02187 }
02188 #endif
02189
02190
02191 #endif
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205 INT ss_sleep(INT millisec)
02206 {
02207 fd_set readfds;
02208 struct timeval timeout;
02209 int status;
02210 static int sock = 0;
02211
02212 if (millisec == 0) {
02213 #ifdef OS_WINNT
02214 SuspendThread(GetCurrentThread());
02215 #endif
02216 #ifdef OS_VMS
02217 sys$hiber();
02218 #endif
02219 #ifdef OS_UNIX
02220 signal(SIGCONT, ss_cont);
02221 pause();
02222 #endif
02223 return SS_SUCCESS;
02224 }
02225 #ifdef OS_WINNT
02226 {
02227 WSADATA WSAData;
02228
02229
02230 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02231 return SS_SOCKET_ERROR;
02232 }
02233 #endif
02234
02235 timeout.tv_sec = millisec / 1000;
02236 timeout.tv_usec = (millisec % 1000) * 1000;
02237
02238 if (!sock)
02239 sock = socket(AF_INET, SOCK_DGRAM, 0);
02240
02241 FD_ZERO(&readfds);
02242 FD_SET(sock, &readfds);
02243 do {
02244 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02245
02246
02247 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02248 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02249
02250 } while (status == -1);
02251
02252 return SS_SUCCESS;
02253 }
02254
02255
02256 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02257
02258
02259 BOOL ss_kbhit()
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 {
02278 #ifdef OS_MSDOS
02279
02280 return kbhit();
02281
02282 #endif
02283 #ifdef OS_WINNT
02284
02285 return kbhit();
02286
02287 #endif
02288 #ifdef OS_VMS
02289
02290 return FALSE;
02291
02292 #endif
02293 #ifdef OS_UNIX
02294
02295 int n;
02296
02297 if (_daemon_flag)
02298 return 0;
02299
02300 ioctl(0, FIONREAD, &n);
02301 return (n > 0);
02302
02303 #endif
02304 #ifdef OS_VXWORKS
02305
02306 int n;
02307 ioctl(0, FIONREAD, (long) &n);
02308 return (n > 0);
02309
02310 #endif
02311 }
02312
02313
02314
02315 #ifdef LOCAL_ROUTINES
02316
02317 INT ss_wake(INT pid, INT tid, INT thandle)
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339 {
02340 #ifdef OS_WINNT
02341 HANDLE process_handle;
02342 HANDLE dup_thread_handle;
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02354
02355 if (process_handle == 0)
02356 return SS_NO_PROCESS;
02357
02358 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02359 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02360
02361
02362 CloseHandle(process_handle);
02363
02364 if (dup_thread_handle == 0)
02365 return SS_NO_PROCESS;
02366
02367 ResumeThread(dup_thread_handle);
02368
02369
02370 CloseHandle(dup_thread_handle);
02371
02372 return SS_SUCCESS;
02373
02374 #endif
02375 #ifdef OS_VMS
02376
02377 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02378 return SS_NO_PROCESS;
02379
02380 return SS_SUCCESS;
02381
02382 #endif
02383 #ifdef OS_UNIX
02384
02385 if (kill(pid, SIGCONT) < 0)
02386 return SS_NO_PROCESS;
02387
02388 return SS_SUCCESS;
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398 #endif
02399 }
02400
02401
02402 #ifdef OS_WINNT
02403
02404 static void (*UserCallback) (int);
02405 static UINT _timer_id = 0;
02406
02407 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02408 DWORD dwReserved1, DWORD dwReserved2)
02409 {
02410 _timer_id = 0;
02411 if (UserCallback != NULL)
02412 UserCallback(0);
02413 }
02414
02415 #endif
02416
02417 INT ss_alarm(INT millitime, void (*func) (int))
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437 {
02438 #ifdef OS_WINNT
02439
02440 UserCallback = func;
02441 if (millitime > 0)
02442 _timer_id =
02443 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
02444 else {
02445 if (_timer_id)
02446 timeKillEvent(_timer_id);
02447 _timer_id = 0;
02448 }
02449
02450 return SS_SUCCESS;
02451
02452 #endif
02453 #ifdef OS_VMS
02454
02455 signal(SIGALRM, func);
02456 alarm(millitime / 1000);
02457 return SS_SUCCESS;
02458
02459 #endif
02460 #ifdef OS_UNIX
02461
02462 signal(SIGALRM, func);
02463 alarm(millitime / 1000);
02464 return SS_SUCCESS;
02465
02466 #endif
02467 }
02468
02469
02470 void (*MidasExceptionHandler) ();
02471
02472 #ifdef OS_WINNT
02473
02474 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02475 {
02476 if (MidasExceptionHandler != NULL)
02477 MidasExceptionHandler();
02478
02479 return EXCEPTION_CONTINUE_SEARCH;
02480 }
02481
02482 INT MidasExceptionSignal(INT sig)
02483 {
02484 if (MidasExceptionHandler != NULL)
02485 MidasExceptionHandler();
02486
02487 raise(sig);
02488
02489 return 0;
02490 }
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 #endif
02503
02504 #ifdef OS_VMS
02505
02506 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02507 {
02508 if (MidasExceptionHandler != NULL)
02509 MidasExceptionHandler();
02510
02511 return (SS$_RESIGNAL);
02512 }
02513
02514 void MidasExceptionSignal(INT sig)
02515 {
02516 if (MidasExceptionHandler != NULL)
02517 MidasExceptionHandler();
02518
02519 kill(getpid(), sig);
02520 }
02521
02522 #endif
02523
02524
02525 INT ss_exception_handler(void (*func) ())
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544 {
02545 #ifdef OS_WINNT
02546
02547 MidasExceptionHandler = func;
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559 #endif
02560 #ifdef OS_VMS
02561
02562 MidasExceptionHandler = func;
02563 lib$establish(MidasExceptionFilter);
02564
02565 signal(SIGINT, MidasExceptionSignal);
02566 signal(SIGILL, MidasExceptionSignal);
02567 signal(SIGQUIT, MidasExceptionSignal);
02568 signal(SIGFPE, MidasExceptionSignal);
02569 signal(SIGSEGV, MidasExceptionSignal);
02570 signal(SIGTERM, MidasExceptionSignal);
02571
02572 #endif
02573
02574 return SS_SUCCESS;
02575 }
02576
02577 #endif
02578
02579
02580 void *ss_ctrlc_handler(void (*func) (int))
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600 {
02601 #ifdef OS_WINNT
02602
02603 if (func == NULL) {
02604 signal(SIGBREAK, SIG_DFL);
02605 return signal(SIGINT, SIG_DFL);
02606 } else {
02607 signal(SIGBREAK, func);
02608 return signal(SIGINT, func);
02609 }
02610 return NULL;
02611
02612 #endif
02613 #ifdef OS_VMS
02614
02615 return signal(SIGINT, func);
02616
02617 #endif
02618
02619 #ifdef OS_UNIX
02620
02621 if (func == NULL) {
02622 signal(SIGTERM, SIG_DFL);
02623 return (void *) signal(SIGINT, SIG_DFL);
02624 } else {
02625 signal(SIGTERM, func);
02626 return (void *) signal(SIGINT, func);
02627 }
02628
02629 #endif
02630 }
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650 typedef struct {
02651 BOOL in_use;
02652 INT thread_id;
02653 INT ipc_port;
02654 INT ipc_recv_socket;
02655 INT ipc_send_socket;
02656 INT(*ipc_dispatch) (char *, INT);
02657 INT listen_socket;
02658 INT(*listen_dispatch) (INT);
02659 RPC_SERVER_CONNECTION *server_connection;
02660 INT(*client_dispatch) (INT);
02661 RPC_SERVER_ACCEPTION *server_acception;
02662 INT(*server_dispatch) (INT, int, BOOL);
02663 struct sockaddr_in bind_addr;
02664 } SUSPEND_STRUCT;
02665
02666 SUSPEND_STRUCT *_suspend_struct = NULL;
02667 INT _suspend_entries;
02668
02669
02670 INT ss_suspend_init_ipc(INT index)
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689 {
02690 INT status, sock;
02691 int i;
02692 struct sockaddr_in bind_addr;
02693 char local_host_name[HOST_NAME_LENGTH];
02694 struct hostent *phe;
02695
02696 #ifdef OS_WINNT
02697 {
02698 WSADATA WSAData;
02699
02700
02701 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02702 return SS_SOCKET_ERROR;
02703 }
02704 #endif
02705
02706
02707 sock = socket(AF_INET, SOCK_DGRAM, 0);
02708 if (sock == -1)
02709 return SS_SOCKET_ERROR;
02710
02711
02712 memset(&bind_addr, 0, sizeof(bind_addr));
02713 bind_addr.sin_family = AF_INET;
02714 bind_addr.sin_addr.s_addr = 0;
02715 bind_addr.sin_port = 0;
02716
02717 gethostname(local_host_name, sizeof(local_host_name));
02718
02719 #ifdef OS_VXWORKS
02720 {
02721 INT host_addr;
02722
02723 host_addr = hostGetByName(local_host_name);
02724 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02725 }
02726 #else
02727 phe = gethostbyname(local_host_name);
02728 if (phe == NULL) {
02729 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
02730 return SS_SOCKET_ERROR;
02731 }
02732 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
02733 #endif
02734
02735 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
02736 if (status < 0)
02737 return SS_SOCKET_ERROR;
02738
02739
02740 i = sizeof(bind_addr);
02741 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
02742
02743 _suspend_struct[index].ipc_recv_socket = sock;
02744 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
02745
02746
02747 sock = socket(AF_INET, SOCK_DGRAM, 0);
02748
02749 if (sock == -1)
02750 return SS_SOCKET_ERROR;
02751
02752
02753 memset(&bind_addr, 0, sizeof(bind_addr));
02754 bind_addr.sin_family = AF_INET;
02755 bind_addr.sin_addr.s_addr = 0;
02756
02757 #ifdef OS_VXWORKS
02758 {
02759 INT host_addr;
02760
02761 host_addr = hostGetByName(local_host_name);
02762 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02763 }
02764 #else
02765 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
02766 #endif
02767
02768 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
02769 _suspend_struct[index].ipc_send_socket = sock;
02770
02771 return SS_SUCCESS;
02772 }
02773
02774
02775 INT ss_suspend_get_index(INT * pindex)
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795 {
02796 INT index;
02797
02798 if (_suspend_struct == NULL) {
02799
02800 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
02801 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
02802 if (_suspend_struct == NULL)
02803 return SS_NO_MEMORY;
02804
02805 _suspend_entries = 1;
02806 *pindex = 0;
02807 _suspend_struct[0].thread_id = ss_gettid();
02808 _suspend_struct[0].in_use = TRUE;
02809 } else {
02810
02811 for (index = 0; index < _suspend_entries; index++)
02812 if (_suspend_struct[index].thread_id == ss_gettid()) {
02813 if (pindex != NULL)
02814 *pindex = index;
02815
02816 return SS_SUCCESS;
02817 }
02818
02819
02820 for (index = 0; index < _suspend_entries; index++)
02821 if (!_suspend_struct[index].in_use)
02822 break;
02823
02824 if (index == _suspend_entries) {
02825
02826 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
02827 sizeof
02828 (SUSPEND_STRUCT) *
02829 (_suspend_entries + 1));
02830 memset(&_suspend_struct[_suspend_entries], 0, sizeof(SUSPEND_STRUCT));
02831
02832 _suspend_entries++;
02833 if (_suspend_struct == NULL) {
02834 _suspend_entries--;
02835 return SS_NO_MEMORY;
02836 }
02837 }
02838 *pindex = index;
02839 _suspend_struct[index].thread_id = ss_gettid();
02840 _suspend_struct[index].in_use = TRUE;
02841 }
02842
02843 return SS_SUCCESS;
02844 }
02845
02846
02847 INT ss_suspend_exit()
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865 {
02866 INT i, status;
02867
02868 status = ss_suspend_get_index(&i);
02869
02870 if (status != SS_SUCCESS)
02871 return status;
02872
02873 if (_suspend_struct[i].ipc_recv_socket) {
02874 closesocket(_suspend_struct[i].ipc_recv_socket);
02875 closesocket(_suspend_struct[i].ipc_send_socket);
02876 }
02877
02878 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
02879
02880
02881 for (i = _suspend_entries - 1; i >= 0; i--)
02882 if (_suspend_struct[i].in_use)
02883 break;
02884
02885 _suspend_entries = i + 1;
02886
02887 if (_suspend_entries == 0) {
02888 free(_suspend_struct);
02889 _suspend_struct = NULL;
02890 }
02891
02892 return SS_SUCCESS;
02893 }
02894
02895
02896 INT ss_suspend_set_dispatch(INT channel, void *connection, INT(*dispatch) ())
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925 {
02926 INT i, status;
02927
02928 status = ss_suspend_get_index(&i);
02929
02930 if (status != SS_SUCCESS)
02931 return status;
02932
02933 if (channel == CH_IPC) {
02934 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
02935
02936 if (!_suspend_struct[i].ipc_recv_socket)
02937 ss_suspend_init_ipc(i);
02938 }
02939
02940 if (channel == CH_LISTEN) {
02941 _suspend_struct[i].listen_socket = *((INT *) connection);
02942 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
02943 }
02944
02945 if (channel == CH_CLIENT) {
02946 _suspend_struct[i].server_connection = (RPC_SERVER_CONNECTION *) connection;
02947 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
02948 }
02949
02950 if (channel == CH_SERVER) {
02951 _suspend_struct[i].server_acception = (RPC_SERVER_ACCEPTION *) connection;
02952 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
02953 }
02954
02955 return SS_SUCCESS;
02956 }
02957
02958
02959 INT ss_suspend_get_port(INT * port)
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980 {
02981 INT index, status;
02982
02983 status = ss_suspend_get_index(&index);
02984
02985 if (status != SS_SUCCESS)
02986 return status;
02987
02988 if (!_suspend_struct[index].ipc_port)
02989 ss_suspend_init_ipc(index);
02990
02991 *port = _suspend_struct[index].ipc_port;
02992
02993 return SS_SUCCESS;
02994 }
02995
02996
02997 INT ss_suspend(INT millisec, INT msg)
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028 {
03029 fd_set readfds;
03030 struct timeval timeout;
03031 INT sock, server_socket;
03032 INT index, status, i, return_status;
03033 int size;
03034 struct sockaddr from_addr;
03035 char str[100], buffer[80], buffer_tmp[80];
03036
03037
03038 status = ss_suspend_get_index(&index);
03039
03040 if (status != SS_SUCCESS)
03041 return status;
03042
03043 return_status = SS_TIMEOUT;
03044
03045 do {
03046 FD_ZERO(&readfds);
03047
03048
03049 if (_suspend_struct[index].listen_socket)
03050 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03051
03052
03053 if (_suspend_struct[index].server_acception)
03054 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03055
03056 sock = _suspend_struct[index].server_acception[i].recv_sock;
03057
03058
03059 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03060 continue;
03061
03062
03063 if (recv_tcp_check(sock) == 0)
03064 FD_SET(sock, &readfds);
03065
03066
03067 else if (msg == 0)
03068 millisec = 0;
03069
03070
03071 sock = _suspend_struct[index].server_acception[i].event_sock;
03072
03073 if (!sock)
03074 continue;
03075
03076
03077 if (recv_event_check(sock) == 0)
03078 FD_SET(sock, &readfds);
03079
03080
03081 else if (msg == 0)
03082 millisec = 0;
03083 }
03084
03085
03086 if (_suspend_struct[index].server_connection) {
03087 sock = _suspend_struct[index].server_connection->recv_sock;
03088 if (sock)
03089 FD_SET(sock, &readfds);
03090 }
03091
03092
03093 if (_suspend_struct[index].ipc_recv_socket)
03094 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03095
03096 timeout.tv_sec = millisec / 1000;
03097 timeout.tv_usec = (millisec % 1000) * 1000;
03098
03099 do {
03100 if (millisec < 0)
03101 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03102 else
03103 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03104
03105
03106 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03107 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03108
03109 } while (status == -1);
03110
03111
03112 if (_suspend_struct[index].listen_socket &&
03113 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03114 sock = _suspend_struct[index].listen_socket;
03115
03116 if (_suspend_struct[index].listen_dispatch) {
03117 status = _suspend_struct[index].listen_dispatch(sock);
03118 if (status == RPC_SHUTDOWN)
03119 return status;
03120 }
03121 }
03122
03123
03124 if (_suspend_struct[index].server_acception)
03125 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03126
03127 sock = _suspend_struct[index].server_acception[i].recv_sock;
03128
03129
03130 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03131 continue;
03132
03133 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03134 if (_suspend_struct[index].server_dispatch) {
03135 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03136 _suspend_struct[index].server_acception[i].
03137 last_activity = ss_millitime();
03138
03139 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03140 return status;
03141
03142 return_status = SS_SERVER_RECV;
03143 }
03144 }
03145
03146
03147 sock = _suspend_struct[index].server_acception[i].event_sock;
03148 if (!sock)
03149 continue;
03150
03151 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03152 if (_suspend_struct[index].server_dispatch) {
03153 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03154 _suspend_struct[index].server_acception[i].
03155 last_activity = ss_millitime();
03156
03157 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03158 return status;
03159
03160 return_status = SS_SERVER_RECV;
03161 }
03162 }
03163 }
03164
03165
03166 if (_suspend_struct[index].server_connection) {
03167 sock = _suspend_struct[index].server_connection->recv_sock;
03168
03169 if (sock && FD_ISSET(sock, &readfds)) {
03170 if (_suspend_struct[index].client_dispatch)
03171 status = _suspend_struct[index].client_dispatch(sock);
03172 else {
03173 status = SS_SUCCESS;
03174 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03175
03176 if (size <= 0)
03177 status = SS_ABORT;
03178 }
03179
03180 if (status == SS_ABORT) {
03181 sprintf(str, "Server connection broken to %s",
03182 _suspend_struct[index].server_connection->host_name);
03183 cm_msg(MINFO, "ss_suspend", str);
03184
03185
03186 closesocket(_suspend_struct[index].server_connection->send_sock);
03187 closesocket(_suspend_struct[index].server_connection->recv_sock);
03188 closesocket(_suspend_struct[index].server_connection->event_sock);
03189
03190 memset(_suspend_struct[index].server_connection,
03191 0, sizeof(RPC_CLIENT_CONNECTION));
03192
03193
03194 return SS_ABORT;
03195 }
03196
03197 return_status = SS_CLIENT_RECV;
03198 }
03199 }
03200
03201
03202 if (_suspend_struct[index].ipc_recv_socket &&
03203 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03204
03205 size = sizeof(struct sockaddr);
03206 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03207 buffer, sizeof(buffer), 0, &from_addr, (int *) &size);
03208
03209
03210 server_socket = 0;
03211 if (_suspend_struct[index].server_acception &&
03212 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03213 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03214 sock = _suspend_struct[index].server_acception[i].send_sock;
03215 if (sock && _suspend_struct[index].server_acception[i].tid == ss_gettid())
03216 server_socket = sock;
03217 }
03218
03219
03220 do {
03221 FD_ZERO(&readfds);
03222 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03223
03224 timeout.tv_sec = 0;
03225 timeout.tv_usec = 0;
03226
03227 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03228
03229 if (status != -1
03230 && FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03231 size = sizeof(struct sockaddr);
03232 size =
03233 recvfrom(_suspend_struct[index].ipc_recv_socket,
03234 buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &size);
03235
03236
03237 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03238 if (_suspend_struct[index].ipc_dispatch)
03239 _suspend_struct[index].ipc_dispatch(buffer_tmp, server_socket);
03240 }
03241
03242 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03243
03244
03245 if (msg == MSG_BM && buffer[0] == 'B')
03246 return SS_SUCCESS;
03247 if (msg == MSG_ODB && buffer[0] == 'O')
03248 return SS_SUCCESS;
03249
03250
03251 if (_suspend_struct[index].ipc_dispatch)
03252 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03253
03254 return_status = SS_SUCCESS;
03255 }
03256
03257 } while (millisec < 0);
03258
03259 return return_status;
03260 }
03261
03262
03263 INT ss_resume(INT port, char *message)
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282
03283
03284
03285
03286 {
03287 INT status, index;
03288
03289 if (ss_in_async_routine_flag) {
03290
03291 index = 0;
03292 } else {
03293 status = ss_suspend_get_index(&index);
03294
03295 if (status != SS_SUCCESS)
03296 return status;
03297 }
03298
03299 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03300
03301 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03302 strlen(message) + 1, 0,
03303 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03304 sizeof(struct sockaddr_in));
03305
03306 if (status != (INT) strlen(message) + 1)
03307 return SS_SOCKET_ERROR;
03308
03309 return SS_SUCCESS;
03310 }
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340 {
03341 DWORD count;
03342 INT status;
03343
03344
03345
03346 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03347 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03348 if (status != -1)
03349 count += status;
03350 else {
03351 cm_msg(MERROR, "send_tcp",
03352 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03353 sock, NET_TCP_SIZE, status, errno, strerror(errno));
03354 return status;
03355 }
03356 }
03357
03358 while (count < buffer_size) {
03359 status = send(sock, buffer + count, buffer_size - count, flags);
03360 if (status != -1)
03361 count += status;
03362 else {
03363 cm_msg(MERROR, "send_tcp",
03364 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03365 sock, (int) (buffer_size - count), status, errno, strerror(errno));
03366 return status;
03367 }
03368 }
03369
03370 return count;
03371 }
03372
03373
03374 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399 {
03400 INT i, status;
03401 DWORD n;
03402 fd_set readfds;
03403 struct timeval timeout;
03404
03405 n = 0;
03406 memset(buffer, 0, buffer_size);
03407
03408 do {
03409 if (millisec > 0) {
03410 FD_ZERO(&readfds);
03411 FD_SET(sock, &readfds);
03412
03413 timeout.tv_sec = millisec / 1000;
03414 timeout.tv_usec = (millisec % 1000) * 1000;
03415
03416 do {
03417 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03418
03419
03420 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03421 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03422
03423 } while (status == -1);
03424
03425 if (!FD_ISSET(sock, &readfds))
03426 break;
03427 }
03428
03429 i = recv(sock, buffer + n, 1, 0);
03430
03431 if (i <= 0)
03432 break;
03433
03434 n++;
03435
03436 if (n >= buffer_size)
03437 break;
03438
03439 } while (buffer[n - 1] && buffer[n - 1] != 10);
03440
03441 return n - 1;
03442 }
03443
03444
03445 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475 {
03476 INT param_size, n_received, n;
03477 NET_COMMAND *nc;
03478
03479 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03480 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03481 return -1;
03482 }
03483
03484
03485 n_received = 0;
03486 do {
03487 #ifdef OS_UNIX
03488 do {
03489 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03490
03491
03492 } while (n == -1 && errno == EINTR);
03493 #else
03494 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03495 #endif
03496
03497 if (n <= 0) {
03498 cm_msg(MERROR, "recv_tcp",
03499 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03500 n, n_received, errno, strerror(errno));
03501 return n;
03502 }
03503
03504 n_received += n;
03505
03506 } while (n_received < sizeof(NET_COMMAND_HEADER));
03507
03508
03509
03510 nc = (NET_COMMAND *) net_buffer;
03511 param_size = nc->header.param_size;
03512 n_received = 0;
03513
03514 if (param_size == 0)
03515 return sizeof(NET_COMMAND_HEADER);
03516
03517 do {
03518 #ifdef OS_UNIX
03519 do {
03520 n = recv(sock,
03521 net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03522 param_size - n_received, flags);
03523
03524
03525 } while (n == -1 && errno == EINTR);
03526 #else
03527 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03528 param_size - n_received, flags);
03529 #endif
03530
03531 if (n <= 0) {
03532 cm_msg(MERROR, "recv_tcp",
03533 "param: recv returned %d, n_received = %d, errno: %d (%s)",
03534 n, n_received, errno, strerror(errno));
03535 return n;
03536 }
03537
03538 n_received += n;
03539 } while (n_received < param_size);
03540
03541 return sizeof(NET_COMMAND_HEADER) + param_size;
03542 }
03543
03544
03545 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568 {
03569 INT status;
03570 UDP_HEADER *udp_header;
03571 static char udp_buffer[NET_UDP_SIZE];
03572 static INT serial_number = 0, n_received = 0;
03573 DWORD i, data_size;
03574
03575 udp_header = (UDP_HEADER *) udp_buffer;
03576 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03577
03578
03579
03580
03581
03582 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03583
03584
03585
03586 if (n_received) {
03587 udp_header->serial_number = UDP_FIRST | n_received;
03588 udp_header->sequence_number = ++serial_number;
03589
03590 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03591 n_received = 0;
03592 }
03593
03594 udp_header->serial_number = UDP_FIRST | buffer_size;
03595 udp_header->sequence_number = ++serial_number;
03596
03597 memcpy(udp_header + 1, buffer, buffer_size);
03598 status = send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03599 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03600 status -= sizeof(UDP_HEADER);
03601
03602 return status;
03603 }
03604
03605
03606
03607
03608
03609 if (buffer_size <= data_size) {
03610
03611 if (buffer_size + n_received < data_size) {
03612 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer, buffer_size);
03613
03614 n_received += buffer_size;
03615 return buffer_size;
03616 }
03617
03618
03619 udp_header->serial_number = UDP_FIRST | n_received;
03620 udp_header->sequence_number = ++serial_number;
03621
03622 status = send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03623
03624 n_received = 0;
03625
03626 memcpy(udp_header + 1, buffer, buffer_size);
03627 n_received = buffer_size;
03628
03629 return buffer_size;
03630 }
03631
03632
03633
03634
03635
03636
03637
03638 if (n_received) {
03639 udp_header->serial_number = UDP_FIRST | n_received;
03640 udp_header->sequence_number = ++serial_number;
03641
03642 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03643 n_received = 0;
03644 }
03645
03646 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03647 if (i == 0) {
03648 udp_header->serial_number = UDP_FIRST | buffer_size;
03649 udp_header->sequence_number = ++serial_number;
03650 } else {
03651 udp_header->serial_number = serial_number;
03652 udp_header->sequence_number = i;
03653 }
03654
03655 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03656 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03657 }
03658
03659
03660 udp_header->serial_number = serial_number;
03661 udp_header->sequence_number = i;
03662 memcpy(udp_header + 1, buffer + i * data_size, buffer_size - i * data_size);
03663 status =
03664 send(sock, udp_buffer, sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03665 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03666 return buffer_size;
03667
03668 return status;
03669 }
03670
03671
03672 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693
03694 {
03695 INT i, status;
03696 UDP_HEADER *udp_header;
03697 char udp_buffer[NET_UDP_SIZE];
03698 DWORD serial_number, sequence_number, total_buffer_size;
03699 DWORD data_size, n_received;
03700 fd_set readfds;
03701 struct timeval timeout;
03702
03703 udp_header = (UDP_HEADER *) udp_buffer;
03704 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03705
03706
03707 #ifdef OS_UNIX
03708 do {
03709 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03710
03711
03712 } while (i == -1 && errno == EINTR);
03713 #else
03714 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03715 #endif
03716
03717 start:
03718
03719
03720 while (!(udp_header->serial_number & UDP_FIRST)) {
03721
03722 FD_ZERO(&readfds);
03723 FD_SET(sock, &readfds);
03724
03725 timeout.tv_sec = 0;
03726 timeout.tv_usec = 100000;
03727
03728 do {
03729 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03730 } while (status == -1);
03731
03732
03733
03734
03735
03736 if (!FD_ISSET(sock, &readfds))
03737 return 0;
03738
03739 #ifdef OS_UNIX
03740 do {
03741 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03742
03743
03744 } while (i == -1 && errno == EINTR);
03745 #else
03746 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03747 #endif
03748 }
03749
03750
03751 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
03752 serial_number = udp_header->sequence_number;
03753 sequence_number = 0;
03754
03755 if (total_buffer_size <= data_size) {
03756 if (buffer_size < total_buffer_size) {
03757 memcpy(buffer, udp_header + 1, buffer_size);
03758 return buffer_size;
03759 } else {
03760 memcpy(buffer, udp_header + 1, total_buffer_size);
03761 return total_buffer_size;
03762 }
03763 }
03764
03765
03766 n_received = data_size;
03767
03768 if (buffer_size < data_size) {
03769 memcpy(buffer, udp_header + 1, buffer_size);
03770 return buffer_size;
03771 }
03772
03773 memcpy(buffer, udp_header + 1, data_size);
03774
03775
03776 do {
03777
03778 FD_ZERO(&readfds);
03779 FD_SET(sock, &readfds);
03780
03781 timeout.tv_sec = 0;
03782 timeout.tv_usec = 100000;
03783
03784 do {
03785 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03786 } while (status == -1);
03787
03788
03789
03790
03791
03792 if (!FD_ISSET(sock, &readfds))
03793 return 0;
03794
03795 #ifdef OS_UNIX
03796 do {
03797 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03798
03799
03800 } while (i == -1 && errno == EINTR);
03801 #else
03802 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03803 #endif
03804
03805 sequence_number++;
03806
03807
03808 if (udp_header->serial_number != serial_number ||
03809 udp_header->sequence_number != sequence_number)
03810
03811 goto start;
03812
03813
03814 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
03815
03816 n_received += (i - sizeof(UDP_HEADER));
03817
03818 } while (n_received < total_buffer_size);
03819
03820 return n_received;
03821 }
03822
03823
03824
03825 #ifdef OS_MSDOS
03826 #ifdef sopen
03827
03828
03829
03830
03831
03832
03833 #undef sopen
03834
03835 int sopen(const char *path, int access, int shflag, int mode)
03836 {
03837 return open(path, (access) | (shflag), mode);
03838 }
03839
03840 #endif
03841 #endif
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851 INT ss_tape_open(char *path, INT oflag, INT * channel)
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873 {
03874 #ifdef OS_UNIX
03875 struct mtop arg;
03876
03877 cm_enable_watchdog(FALSE);
03878
03879 *channel = open(path, oflag, 0644);
03880
03881 cm_enable_watchdog(TRUE);
03882
03883 if (*channel < 0)
03884 cm_msg(MERROR, "ss_tape_open", strerror(errno));
03885
03886 if (*channel < 0) {
03887 if (errno == EIO)
03888 return SS_NO_TAPE;
03889 if (errno == EBUSY)
03890 return SS_DEV_BUSY;
03891 return errno;
03892 }
03893 #ifdef MTSETBLK
03894
03895 arg.mt_op = MTSETBLK;
03896 arg.mt_count = 0;
03897
03898 ioctl(*channel, MTIOCTOP, &arg);
03899 #endif
03900
03901 #endif
03902
03903 #ifdef OS_WINNT
03904 INT status;
03905 TAPE_GET_MEDIA_PARAMETERS m;
03906
03907 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
03908 0, OPEN_EXISTING, 0, NULL);
03909
03910 if (*channel == (INT) INVALID_HANDLE_VALUE) {
03911 status = GetLastError();
03912 if (status == ERROR_SHARING_VIOLATION) {
03913 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
03914 return SS_DEV_BUSY;
03915 }
03916 if (status == ERROR_FILE_NOT_FOUND) {
03917 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
03918 return SS_NO_TAPE;
03919 }
03920
03921 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
03922 return status;
03923 }
03924
03925 status = GetTapeStatus((HANDLE) (*channel));
03926 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
03927 cm_msg(MERROR, "ss_tape_open", "no media in drive");
03928 return SS_NO_TAPE;
03929 }
03930
03931
03932 memset(&m, 0, sizeof(m));
03933 m.BlockSize = TAPE_BUFFER_SIZE;
03934 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
03935
03936 #endif
03937
03938 return SS_SUCCESS;
03939 }
03940
03941
03942 INT ss_tape_close(INT channel)
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960 {
03961 INT status;
03962
03963 #ifdef OS_UNIX
03964
03965 status = close(channel);
03966
03967 if (status < 0) {
03968 cm_msg(MERROR, "ss_tape_close", strerror(errno));
03969 return errno;
03970 }
03971 #endif
03972
03973 #ifdef OS_WINNT
03974
03975 if (!CloseHandle((HANDLE) channel)) {
03976 status = GetLastError();
03977 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
03978 return status;
03979 }
03980 #endif
03981
03982 return SS_SUCCESS;
03983 }
03984
03985
03986 INT ss_tape_status(char *path)
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003 {
04004 #ifdef OS_UNIX
04005 char str[256];
04006
04007 sprintf(str, "mt -f %s status", path);
04008 system(str);
04009 #endif
04010
04011 #ifdef OS_WINNT
04012 INT status, channel;
04013 DWORD size;
04014 TAPE_GET_MEDIA_PARAMETERS m;
04015 TAPE_GET_DRIVE_PARAMETERS d;
04016 double x;
04017
04018 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04019 0, OPEN_EXISTING, 0, NULL);
04020
04021 if (channel == (INT) INVALID_HANDLE_VALUE) {
04022 status = GetLastError();
04023 if (status == ERROR_SHARING_VIOLATION) {
04024 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04025 return SS_SUCCESS;
04026 }
04027 if (status == ERROR_FILE_NOT_FOUND) {
04028 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
04029 return SS_SUCCESS;
04030 }
04031
04032 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04033 return status;
04034 }
04035
04036
04037 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04038 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04039
04040 status = GetTapeStatus((HANDLE) channel);
04041 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04042 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04043 CloseHandle((HANDLE) channel);
04044 return SS_SUCCESS;
04045 }
04046
04047 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04048 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
04049
04050 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04051 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04052 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04053
04054 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04055 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
04056 / 1024.0 / 1000.0;
04057 printf("Tape capacity remaining is %d MB\n", (int) x);
04058 } else
04059 printf("Tape capacity is not reported by tape\n");
04060
04061 CloseHandle((HANDLE) channel);
04062
04063 #endif
04064
04065 return SS_SUCCESS;
04066 }
04067
04068
04069 INT ss_tape_write(INT channel, void *pdata, INT count)
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090 {
04091 #ifdef OS_UNIX
04092 INT status;
04093
04094 do {
04095 status = write(channel, pdata, count);
04096
04097
04098
04099
04100 } while (status == -1 && errno == EINTR);
04101
04102 if (status != count) {
04103 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04104
04105 if (errno == EIO)
04106 return SS_IO_ERROR;
04107 else
04108 return SS_TAPE_ERROR;
04109 }
04110 #endif
04111
04112 #ifdef OS_WINNT
04113 INT status;
04114 DWORD written;
04115
04116 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04117 if (written != (DWORD) count) {
04118 status = GetLastError();
04119 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04120
04121 return SS_IO_ERROR;
04122 }
04123 #endif
04124
04125 return SS_SUCCESS;
04126 }
04127
04128
04129 INT ss_tape_read(INT channel, void *pdata, INT * count)
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149 {
04150 #ifdef OS_UNIX
04151 INT n, status;
04152
04153 do {
04154 n = read(channel, pdata, *count);
04155 } while (n == -1 && errno == EINTR);
04156
04157 if (n == -1) {
04158 if (errno == ENOSPC || errno == EIO)
04159 status = SS_END_OF_TAPE;
04160 else {
04161 if (n == 0 && errno == 0)
04162 status = SS_END_OF_FILE;
04163 else {
04164 cm_msg(MERROR, "ss_tape_read",
04165 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04166 status = errno;
04167 }
04168 }
04169 } else
04170 status = SS_SUCCESS;
04171 *count = n;
04172
04173 return status;
04174
04175 #elif defined(OS_WINNT)
04176
04177 INT status;
04178 DWORD read;
04179
04180 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04181 status = GetLastError();
04182 if (status == ERROR_NO_DATA_DETECTED)
04183 status = SS_END_OF_TAPE;
04184 else if (status == ERROR_FILEMARK_DETECTED)
04185 status = SS_END_OF_FILE;
04186 else if (status == ERROR_MORE_DATA)
04187 status = SS_SUCCESS;
04188 else
04189 cm_msg(MERROR, "ss_tape_read",
04190 "unexpected tape error: n=%d, errno=%d\n", read, status);
04191 } else
04192 status = SS_SUCCESS;
04193
04194 *count = read;
04195 return status;
04196
04197 #else
04198
04199 return SS_SUCCESS;
04200
04201 #endif
04202 }
04203
04204
04205 INT ss_tape_write_eof(INT channel)
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223 {
04224 INT status;
04225
04226 #ifdef OS_UNIX
04227 struct mtop arg;
04228
04229 arg.mt_op = MTWEOF;
04230 arg.mt_count = 1;
04231
04232 cm_enable_watchdog(FALSE);
04233
04234 status = ioctl(channel, MTIOCTOP, &arg);
04235
04236 cm_enable_watchdog(TRUE);
04237
04238 if (status < 0) {
04239 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04240 return errno;
04241 }
04242 #endif
04243
04244 #ifdef OS_WINNT
04245
04246 TAPE_GET_DRIVE_PARAMETERS d;
04247 DWORD size;
04248
04249 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04250 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04251
04252 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04253 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04254 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04255 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04256 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04257 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04258 else
04259 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
04260
04261 if (status != NO_ERROR) {
04262 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04263 return status;
04264 }
04265 #endif
04266
04267 return SS_SUCCESS;
04268 }
04269
04270
04271 INT ss_tape_fskip(INT channel, INT count)
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290 {
04291 INT status;
04292
04293 #ifdef OS_UNIX
04294 struct mtop arg;
04295
04296 if (count > 0)
04297 arg.mt_op = MTFSF;
04298 else
04299 arg.mt_op = MTBSF;
04300 arg.mt_count = abs(count);
04301
04302 cm_enable_watchdog(FALSE);
04303
04304 status = ioctl(channel, MTIOCTOP, &arg);
04305
04306 cm_enable_watchdog(TRUE);
04307
04308 if (status < 0) {
04309 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04310 return errno;
04311 }
04312 #endif
04313
04314 #ifdef OS_WINNT
04315
04316 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04317 (DWORD) count, 0, FALSE);
04318
04319 if (status == ERROR_END_OF_MEDIA)
04320 return SS_END_OF_TAPE;
04321
04322 if (status != NO_ERROR) {
04323 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04324 return status;
04325 }
04326 #endif
04327
04328 return SS_SUCCESS;
04329 }
04330
04331
04332 INT ss_tape_rskip(INT channel, INT count)
04333
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351 {
04352 INT status;
04353
04354 #ifdef OS_UNIX
04355 struct mtop arg;
04356
04357 if (count > 0)
04358 arg.mt_op = MTFSR;
04359 else
04360 arg.mt_op = MTBSR;
04361 arg.mt_count = abs(count);
04362
04363 cm_enable_watchdog(FALSE);
04364
04365 status = ioctl(channel, MTIOCTOP, &arg);
04366
04367 cm_enable_watchdog(TRUE);
04368
04369 if (status < 0) {
04370 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04371 return errno;
04372 }
04373 #endif
04374
04375 #ifdef OS_WINNT
04376
04377 status =
04378 SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04379 (DWORD) count, 0, FALSE);
04380 if (status != NO_ERROR) {
04381 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04382 return status;
04383 }
04384 #endif
04385
04386 return CM_SUCCESS;
04387 }
04388
04389
04390 INT ss_tape_rewind(INT channel)
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408 {
04409 INT status;
04410
04411 #ifdef OS_UNIX
04412 struct mtop arg;
04413
04414 arg.mt_op = MTREW;
04415 arg.mt_count = 0;
04416
04417 cm_enable_watchdog(FALSE);
04418
04419 status = ioctl(channel, MTIOCTOP, &arg);
04420
04421 cm_enable_watchdog(TRUE);
04422
04423 if (status < 0) {
04424 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04425 return errno;
04426 }
04427 #endif
04428
04429 #ifdef OS_WINNT
04430
04431 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04432 if (status != NO_ERROR) {
04433 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04434 return status;
04435 }
04436 #endif
04437
04438 return CM_SUCCESS;
04439 }
04440
04441
04442 INT ss_tape_spool(INT channel)
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460 {
04461 INT status;
04462
04463 #ifdef OS_UNIX
04464 struct mtop arg;
04465
04466 #ifdef MTEOM
04467 arg.mt_op = MTEOM;
04468 #else
04469 arg.mt_op = MTSEOD;
04470 #endif
04471 arg.mt_count = 0;
04472
04473 cm_enable_watchdog(FALSE);
04474
04475 status = ioctl(channel, MTIOCTOP, &arg);
04476
04477 cm_enable_watchdog(TRUE);
04478
04479 if (status < 0) {
04480 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04481 return errno;
04482 }
04483 #endif
04484
04485 #ifdef OS_WINNT
04486
04487 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
04488 if (status != NO_ERROR) {
04489 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04490 return status;
04491 }
04492 #endif
04493
04494 return CM_SUCCESS;
04495 }
04496
04497
04498 INT ss_tape_mount(INT channel)
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516 {
04517 INT status;
04518
04519 #ifdef OS_UNIX
04520 struct mtop arg;
04521
04522 #ifdef MTLOAD
04523 arg.mt_op = MTLOAD;
04524 #else
04525 arg.mt_op = MTNOP;
04526 #endif
04527 arg.mt_count = 0;
04528
04529 cm_enable_watchdog(FALSE);
04530
04531 status = ioctl(channel, MTIOCTOP, &arg);
04532
04533 cm_enable_watchdog(TRUE);
04534
04535 if (status < 0) {
04536 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04537 return errno;
04538 }
04539 #endif
04540
04541 #ifdef OS_WINNT
04542
04543 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04544 if (status != NO_ERROR) {
04545 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04546 return status;
04547 }
04548 #endif
04549
04550 return CM_SUCCESS;
04551 }
04552
04553
04554 INT ss_tape_unmount(INT channel)
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572 {
04573 INT status;
04574
04575 #ifdef OS_UNIX
04576 struct mtop arg;
04577
04578 #ifdef MTOFFL
04579 arg.mt_op = MTOFFL;
04580 #else
04581 arg.mt_op = MTUNLOAD;
04582 #endif
04583 arg.mt_count = 0;
04584
04585 cm_enable_watchdog(FALSE);
04586
04587 status = ioctl(channel, MTIOCTOP, &arg);
04588
04589 cm_enable_watchdog(TRUE);
04590
04591 if (status < 0) {
04592 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04593 return errno;
04594 }
04595 #endif
04596
04597 #ifdef OS_WINNT
04598
04599 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04600 if (status != NO_ERROR) {
04601 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04602 return status;
04603 }
04604 #endif
04605
04606 return CM_SUCCESS;
04607 }
04608
04609
04610 INT ss_tape_get_blockn(INT channel)
04611
04612
04613
04614
04615
04616
04617
04618
04619 {
04620 #if defined(OS_DARWIN)
04621
04622 return 0;
04623
04624 #elif defined(OS_UNIX)
04625
04626 INT status;
04627 struct mtpos arg;
04628
04629 cm_enable_watchdog(FALSE);
04630 status = ioctl(channel, MTIOCPOS, &arg);
04631 cm_enable_watchdog(TRUE);
04632 if (status < 0) {
04633 if (errno == EIO)
04634 return 0;
04635 else {
04636 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04637 return -errno;
04638 }
04639 }
04640 return (arg.mt_blkno);
04641
04642 #elif defined(OS_WINNT)
04643
04644 INT status;
04645 TAPE_GET_MEDIA_PARAMETERS media;
04646 unsigned long size;
04647
04648 status =
04649 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
04650 return (media.PartitionCount);
04651
04652 #endif
04653 }
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664 double ss_disk_free(char *path)
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680 {
04681 #ifdef OS_UNIX
04682 #if defined(OS_OSF1)
04683 struct statfs st;
04684 statfs(path, &st, sizeof(st));
04685 return (double) st.f_bavail * st.f_bsize;
04686 #elif defined(OS_LINUX)
04687 struct statfs st;
04688 statfs(path, &st);
04689 return (double) st.f_bavail * st.f_bsize;
04690 #elif defined(OS_SOLARIS)
04691 struct statvfs st;
04692 statvfs(path, &st);
04693 return (double) st.f_bavail * st.f_bsize;
04694 #elif defined(OS_IRIX)
04695 struct statfs st;
04696 statfs(path, &st, sizeof(struct statfs), 0);
04697 return (double) st.f_bfree * st.f_bsize;
04698 #else
04699 struct fs_data st;
04700 statfs(path, &st);
04701 return (double) st.fd_otsize * st.fd_bfree;
04702 #endif
04703
04704 #elif defined(OS_WINNT)
04705 DWORD SectorsPerCluster;
04706 DWORD BytesPerSector;
04707 DWORD NumberOfFreeClusters;
04708 DWORD TotalNumberOfClusters;
04709 char str[80];
04710
04711 strcpy(str, path);
04712 if (strchr(str, ':') != NULL) {
04713 *(strchr(str, ':') + 1) = 0;
04714 strcat(str, DIR_SEPARATOR_STR);
04715 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04716 &NumberOfFreeClusters, &TotalNumberOfClusters);
04717 } else
04718 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04719 &NumberOfFreeClusters, &TotalNumberOfClusters);
04720
04721 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
04722 #else
04723
04724 return 1e9;
04725
04726 #endif
04727 }
04728
04729 #if defined(OS_ULTRIX) || defined(OS_WINNT)
04730 int fnmatch(const char *pat, const char *str, const int flag)
04731 {
04732 while (*str != '\0') {
04733 if (*pat == '*') {
04734 pat++;
04735 if ((str = strchr(str, *pat)) == NULL)
04736 return -1;
04737 }
04738 if (*pat == *str) {
04739 pat++;
04740 str++;
04741 } else
04742 return -1;
04743 }
04744 if (*pat == '\0')
04745 return 0;
04746 else
04747 return -1;
04748 }
04749 #endif
04750
04751 #ifdef OS_WINNT
04752 HANDLE pffile;
04753 LPWIN32_FIND_DATA lpfdata;
04754 #endif
04755 INT ss_file_find(char *path, char *pattern, char **plist)
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773 {
04774 int i;
04775 #ifdef OS_UNIX
04776 DIR *dir_pointer;
04777 struct dirent *dp;
04778
04779 if ((dir_pointer = opendir(path)) == NULL)
04780 return 0;
04781 *plist = (char *) malloc(MAX_STRING_LENGTH);
04782 i = 0;
04783 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
04784 if (fnmatch(pattern, dp->d_name, 0) == 0) {
04785 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04786 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name, strlen(dp->d_name));
04787 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
04788 i++;
04789 seekdir(dir_pointer, telldir(dir_pointer));
04790 }
04791 }
04792 closedir(dir_pointer);
04793 #endif
04794 #ifdef OS_WINNT
04795 char str[255];
04796 int first;
04797
04798 strcpy(str, path);
04799 strcat(str, "\\");
04800 strcat(str, pattern);
04801 first = 1;
04802 i = 0;
04803 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
04804 *plist = (char *) malloc(MAX_STRING_LENGTH);
04805 pffile = FindFirstFile(str, lpfdata);
04806 if (pffile == INVALID_HANDLE_VALUE)
04807 return 0;
04808 first = 0;
04809 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04810 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
04811 strlen(lpfdata->cFileName));
04812 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
04813 i++;
04814 while (FindNextFile(pffile, lpfdata)) {
04815 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
04816 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
04817 strlen(lpfdata->cFileName));
04818 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
04819 i++;
04820 }
04821 free(lpfdata);
04822 #endif
04823 return i;
04824 }
04825
04826 INT ss_file_remove(char *path)
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842 {
04843 return remove(path);
04844 }
04845
04846 double ss_file_size(char *path)
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
04862 {
04863 struct stat stat_buf;
04864
04865
04866 stat(path, &stat_buf);
04867 return (double) stat_buf.st_size;
04868 }
04869
04870 double ss_disk_size(char *path)
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883
04884
04885
04886 {
04887 #ifdef OS_UNIX
04888 #if defined(OS_OSF1)
04889 struct statfs st;
04890 statfs(path, &st, sizeof(st));
04891 return (double) st.f_blocks * st.f_fsize;
04892 #elif defined(OS_LINUX)
04893 struct statfs st;
04894 statfs(path, &st);
04895 return (double) st.f_blocks * st.f_bsize;
04896 #elif defined(OS_SOLARIS)
04897 struct statvfs st;
04898 statvfs(path, &st);
04899 if (st.f_frsize > 0)
04900 return (double) st.f_blocks * st.f_frsize;
04901 else
04902 return (double) st.f_blocks * st.f_bsize;
04903 #elif defined(OS_ULTRIX)
04904 struct fs_data st;
04905 statfs(path, &st);
04906 return (double) st.fd_btot * 1024;
04907 #elif defined(OS_IRIX)
04908 struct statfs st;
04909 statfs(path, &st, sizeof(struct statfs), 0);
04910 return (double) st.f_blocks * st.f_bsize;
04911 #else
04912 #error ss_disk_size not defined for this OS
04913 #endif
04914 #endif
04915
04916 #ifdef OS_WINNT
04917 DWORD SectorsPerCluster;
04918 DWORD BytesPerSector;
04919 DWORD NumberOfFreeClusters;
04920 DWORD TotalNumberOfClusters;
04921 char str[80];
04922
04923 strcpy(str, path);
04924 if (strchr(str, ':') != NULL) {
04925 *(strchr(str, ':') + 1) = 0;
04926 strcat(str, DIR_SEPARATOR_STR);
04927 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04928 &NumberOfFreeClusters, &TotalNumberOfClusters);
04929 } else
04930 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04931 &NumberOfFreeClusters, &TotalNumberOfClusters);
04932
04933 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
04934 #endif
04935
04936 return 1e9;
04937 }
04938
04939
04940
04941
04942
04943
04944
04945
04946
04947 void ss_clear_screen()
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961
04962
04963
04964 {
04965 #ifdef OS_WINNT
04966
04967 HANDLE hConsole;
04968 COORD coordScreen = { 0, 0 };
04969 BOOL bSuccess;
04970 DWORD cCharsWritten;
04971 CONSOLE_SCREEN_BUFFER_INFO csbi;
04972 DWORD dwConSize;
04973
04974 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
04975
04976
04977 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
04978 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
04979
04980
04981 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
04982 dwConSize, coordScreen, &cCharsWritten);
04983
04984
04985 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
04986 return;
04987
04988 #endif
04989 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
04990 printf("\033[2J");
04991 #endif
04992 #ifdef OS_MSDOS
04993 clrscr();
04994 #endif
04995 }
04996
04997
04998 void ss_set_screen_size(int x, int y)
04999
05000
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015 {
05016 #ifdef OS_WINNT
05017
05018 HANDLE hConsole;
05019 COORD coordSize;
05020
05021 coordSize.X = (short) x;
05022 coordSize.Y = (short) y;
05023 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05024 SetConsoleScreenBufferSize(hConsole, coordSize);
05025
05026 #endif
05027 }
05028
05029
05030 void ss_printf(INT x, INT y, const char *format, ...)
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047
05048
05049
05050
05051 {
05052 char str[256];
05053 va_list argptr;
05054
05055 va_start(argptr, format);
05056 vsprintf(str, (char *) format, argptr);
05057 va_end(argptr);
05058
05059 #ifdef OS_WINNT
05060 {
05061 HANDLE hConsole;
05062 COORD dwWriteCoord;
05063 DWORD cCharsWritten;
05064
05065 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05066
05067 dwWriteCoord.X = (short) x;
05068 dwWriteCoord.Y = (short) y;
05069
05070 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05071 dwWriteCoord, &cCharsWritten);
05072 }
05073
05074 #endif
05075
05076 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05077 printf("\033[%1d;%1d;H", y + 1, x + 1);
05078 printf(str);
05079 fflush(stdout);
05080 #endif
05081
05082 #ifdef OS_MSDOS
05083 gotoxy(x + 1, y + 1);
05084 cputs(str);
05085 #endif
05086 }
05087
05088
05089 char *ss_getpass(char *prompt)
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104
05105
05106 {
05107 static char password[32];
05108
05109 printf(prompt);
05110 memset(password, 0, sizeof(password));
05111
05112 #ifdef OS_UNIX
05113 return (char *) getpass("");
05114 #elif defined(OS_WINNT)
05115 {
05116 HANDLE hConsole;
05117 DWORD nCharsRead;
05118
05119 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05120 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05121 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05122 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05123 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05124 printf("\n");
05125
05126 if (password[strlen(password) - 1] == '\r')
05127 password[strlen(password) - 1] = 0;
05128
05129 return password;
05130 }
05131 #elif defined(OS_MSDOS)
05132 {
05133 char c, *ptr;
05134
05135 ptr = password;
05136 while ((c = getchar()) != EOF && c != '\n')
05137 *ptr++ = c;
05138 *ptr = 0;
05139
05140 printf("\n");
05141 return password;
05142 }
05143 #else
05144 {
05145 ss_gets(password, 32);
05146 return password;
05147 }
05148 #endif
05149 }
05150
05151
05152 INT ss_getchar(BOOL reset)
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172 {
05173 #ifdef OS_UNIX
05174
05175 static BOOL init = FALSE;
05176 static struct termios save_termios;
05177 struct termios buf;
05178 int i, fd;
05179 char c[3];
05180
05181 if (_daemon_flag)
05182 return 0;
05183
05184 fd = fileno(stdin);
05185
05186 if (reset) {
05187 if (init)
05188 tcsetattr(fd, TCSAFLUSH, &save_termios);
05189 init = FALSE;
05190 return 0;
05191 }
05192
05193 if (!init) {
05194 tcgetattr(fd, &save_termios);
05195 memcpy(&buf, &save_termios, sizeof(buf));
05196
05197 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05198
05199 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05200
05201 buf.c_cflag &= ~(CSIZE | PARENB);
05202 buf.c_cflag |= CS8;
05203
05204 buf.c_cc[VMIN] = 0;
05205 buf.c_cc[VTIME] = 0;
05206
05207 tcsetattr(fd, TCSAFLUSH, &buf);
05208 init = TRUE;
05209 }
05210
05211 memset(c, 0, 3);
05212 i = read(fd, c, 1);
05213
05214 if (i == 0)
05215 return 0;
05216
05217
05218 if (c[0] == 27) {
05219 i = read(fd, c, 2);
05220 if (i == 0)
05221 return 27;
05222
05223
05224 if (c[1] < 65)
05225 read(fd, c, 1);
05226
05227
05228 switch (c[1]) {
05229 case 49:
05230 return CH_HOME;
05231 case 50:
05232 return CH_INSERT;
05233 case 51:
05234 return CH_DELETE;
05235 case 52:
05236 return CH_END;
05237 case 53:
05238 return CH_PUP;
05239 case 54:
05240 return CH_PDOWN;
05241 case 65:
05242 return CH_UP;
05243 case 66:
05244 return CH_DOWN;
05245 case 67:
05246 return CH_RIGHT;
05247 case 68:
05248 return CH_LEFT;
05249 }
05250 }
05251
05252
05253 if (c[0] == 127)
05254 return CH_BS;
05255
05256 return c[0];
05257
05258 #elif defined(OS_WINNT)
05259
05260 static BOOL init = FALSE;
05261 static INT repeat_count = 0;
05262 static INT repeat_char;
05263 HANDLE hConsole;
05264 DWORD nCharsRead;
05265 INPUT_RECORD ir;
05266 OSVERSIONINFO vi;
05267
05268
05269 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05270 GetVersionEx(&vi);
05271
05272 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05273
05274 int c;
05275
05276 if (!kbhit())
05277 return 0;
05278
05279 c = getch();
05280 if (c == 224) {
05281 c = getch();
05282 switch (c) {
05283 case 71:
05284 return CH_HOME;
05285 case 72:
05286 return CH_UP;
05287 case 73:
05288 return CH_PUP;
05289 case 75:
05290 return CH_LEFT;
05291 case 77:
05292 return CH_RIGHT;
05293 case 79:
05294 return CH_END;
05295 case 80:
05296 return CH_DOWN;
05297 case 81:
05298 return CH_PDOWN;
05299 case 82:
05300 return CH_INSERT;
05301 case 83:
05302 return CH_DELETE;
05303 }
05304 }
05305 return c;
05306 }
05307
05308 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05309
05310 if (reset) {
05311 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05312 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05313 init = FALSE;
05314 return 0;
05315 }
05316
05317 if (!init) {
05318 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05319 init = TRUE;
05320 }
05321
05322 if (repeat_count) {
05323 repeat_count--;
05324 return repeat_char;
05325 }
05326
05327 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05328
05329 if (nCharsRead == 0)
05330 return 0;
05331
05332 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05333
05334 if (ir.EventType != KEY_EVENT)
05335 return ss_getchar(0);
05336
05337 if (!ir.Event.KeyEvent.bKeyDown)
05338 return ss_getchar(0);
05339
05340 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05341 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05342 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05343 return repeat_char;
05344 }
05345
05346 if (ir.Event.KeyEvent.uChar.AsciiChar)
05347 return ir.Event.KeyEvent.uChar.AsciiChar;
05348
05349 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05350 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05351 case 33:
05352 return CH_PUP;
05353 case 34:
05354 return CH_PDOWN;
05355 case 35:
05356 return CH_END;
05357 case 36:
05358 return CH_HOME;
05359 case 37:
05360 return CH_LEFT;
05361 case 38:
05362 return CH_UP;
05363 case 39:
05364 return CH_RIGHT;
05365 case 40:
05366 return CH_DOWN;
05367 case 45:
05368 return CH_INSERT;
05369 case 46:
05370 return CH_DELETE;
05371 }
05372
05373 return ir.Event.KeyEvent.wVirtualKeyCode;
05374 }
05375
05376 return ss_getchar(0);
05377
05378 #elif defined(OS_MSDOS)
05379
05380 int c;
05381
05382 if (!kbhit())
05383 return 0;
05384
05385 c = getch();
05386 if (!c) {
05387 c = getch();
05388 switch (c) {
05389 case 71:
05390 return CH_HOME;
05391 case 72:
05392 return CH_UP;
05393 case 73:
05394 return CH_PUP;
05395 case 75:
05396 return CH_LEFT;
05397 case 77:
05398 return CH_RIGHT;
05399 case 79:
05400 return CH_END;
05401 case 80:
05402 return CH_DOWN;
05403 case 81:
05404 return CH_PDOWN;
05405 case 82:
05406 return CH_INSERT;
05407 case 83:
05408 return CH_DELETE;
05409 }
05410 }
05411 return c;
05412
05413 #else
05414 return -1;
05415 #endif
05416 }
05417
05418
05419 char *ss_gets(char *string, int size)
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438 {
05439 char *p;
05440
05441 do {
05442 p = fgets(string, size, stdin);
05443 } while (p == NULL);
05444
05445
05446 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05447 p[strlen(p) - 1] = 0;
05448
05449 return p;
05450 }
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460 INT ss_directio_give_port(INT start, INT end)
05461 {
05462 #ifdef OS_WINNT
05463
05464
05465
05466 OSVERSIONINFO vi;
05467 HANDLE hdio = 0;
05468 DWORD buffer[] = { 6, 0, 0, 0 };
05469 DWORD size;
05470
05471 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05472 GetVersionEx(&vi);
05473
05474
05475 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05476 hdio =
05477 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05478 NULL, OPEN_EXISTING, 0, NULL);
05479 if (hdio == INVALID_HANDLE_VALUE) {
05480 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05481 return -1;
05482 }
05483
05484
05485 buffer[1] = start;
05486 buffer[2] = end;
05487 if (!DeviceIoControl
05488 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05489 return -1;
05490 }
05491
05492 return SS_SUCCESS;
05493 #else
05494 return SS_SUCCESS;
05495 #endif
05496 }
05497
05498
05499 INT ss_directio_lock_port(INT start, INT end)
05500 {
05501 #ifdef OS_WINNT
05502
05503
05504
05505 OSVERSIONINFO vi;
05506 HANDLE hdio;
05507 DWORD buffer[] = { 7, 0, 0, 0 };
05508 DWORD size;
05509
05510 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05511 GetVersionEx(&vi);
05512
05513
05514 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05515 hdio =
05516 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05517 NULL, OPEN_EXISTING, 0, NULL);
05518 if (hdio == INVALID_HANDLE_VALUE) {
05519 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05520 return -1;
05521 }
05522
05523
05524 buffer[1] = start;
05525 buffer[2] = end;
05526 if (!DeviceIoControl
05527 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05528 return -1;
05529 }
05530
05531 return SS_SUCCESS;
05532 #else
05533 return SS_SUCCESS;
05534 #endif
05535 }
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545 INT ss_syslog(const char *message)
05546
05547
05548
05549
05550
05551
05552
05553
05554
05555
05556
05557
05558
05559
05560
05561
05562 {
05563 #ifdef OS_UNIX
05564 static BOOL init = FALSE;
05565
05566 if (!init) {
05567 #ifdef OS_ULTRIX
05568 openlog("MIDAS", LOG_PID);
05569 #else
05570 openlog("MIDAS", LOG_PID, LOG_USER);
05571 #endif
05572 init = TRUE;
05573 }
05574
05575 syslog(LOG_DEBUG, message);
05576 return SS_SUCCESS;
05577 #elif defined(OS_WINNT)
05578
05579
05580
05581
05582
05583
05584
05585
05586
05587
05588
05589
05590
05591
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607
05608 return SS_SUCCESS;
05609
05610 #else
05611
05612 return SS_SUCCESS;
05613
05614 #endif
05615 }
05616
05617
05618
05619
05620
05621
05622
05623
05624 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05625
05626 char *ss_crypt(char *buf, char *salt)
05627
05628
05629
05630
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640
05641
05642
05643
05644
05645
05646 {
05647 int i, seed;
05648 static char enc_pw[13];
05649
05650 memset(enc_pw, 0, sizeof(enc_pw));
05651 enc_pw[0] = salt[0];
05652 enc_pw[1] = salt[1];
05653
05654 for (i = 0; i < 8 && buf[i]; i++)
05655 enc_pw[i + 2] = buf[i];
05656 for (; i < 8; i++)
05657 enc_pw[i + 2] = 0;
05658
05659 seed = 123;
05660 for (i = 2; i < 13; i++) {
05661 seed = 5 * seed + 27 + enc_pw[i];
05662 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05663 }
05664
05665 return enc_pw;
05666 }
05667
05668
05669
05670
05671
05672
05673
05674
05675 double ss_nan()
05676 {
05677 double nan;
05678
05679 nan = 0;
05680 nan = 0/nan;
05681 return nan;
05682 }
05683 #ifdef OS_WINNT
05684 #include <float.h>
05685 #ifndef isnan
05686 #define isnan(x) _isnan(x)
05687 #endif
05688 #elif defined(OS_LINUX)
05689 #include <math.h>
05690 #endif
05691
05692 int ss_isnan(double x)
05693 {
05694 return isnan(x);
05695 }
05696
05697
05698 #endif
05699
05700
05701
05702